今天思考下前端源碼安全的東西(不是前端安全,只是針對於源碼部分)。在我看來,源碼安全有兩點,一是防止抄襲,二是防止被攻破。實際上講,前端的代碼大可能是沒有什麼可抄襲性,安全更是形同虛設的(任何前端輸入都是不能相信的)。但若是仍是想防止源碼被查看,HTML、CSS並不能作什麼,最終都會用露出來(最簡單用Chrome開發者工具就能夠看到),因此只能針對JS作文件的壓縮合並和混淆。css
關於抄襲html
其實就前端來說,代碼沒有什麼好抄襲的,大多人都是抄UI設計(這個是躲不了),還有一些富前端的控件和算法,重要之處仍是在於後端,然後端是抄不了的。因此前端文件壓縮合並,目的並非防止抄襲,而是爲了減小文件體積、加快載入速度,提升程序的執行性能,固然壓縮也有混淆的功能。文件混淆是防止其餘人查看代碼邏輯,可是生成的代碼比原代碼體積大得多,因此文件若是作了混淆,加載速度和執行速度都會有所降低。前端
關於安全node
全部的用戶輸入都是不能相信的,若是後端的檢查校驗還作得很差,那就可能被攻破。前端代碼的邏輯若是還被瞭解清楚,那就是雪上加霜。後端的問題咱們前端管不着,前端的代碼安全,簡單的能夠用壓縮解決、再進一步就去混淆,讓別人看不懂。算法
HTML壓縮express
不多有人去作HTML的壓縮(特指去除空白字符和註釋),根據其餘資料有幾個緣由:json
1. HTML文檔中,多個空白字符等價爲一個空白字符。也就是說換行等空白字符的刪除是不安全的,可能致使元素的樣式產生差別。後端
2. HTML元素中,有一個pre, 表示 preformatted text. 裏面的任何空白,都不能被刪除。sass
3. HTML中有可能有 IE 條件註釋。這些條件註釋是文檔邏輯的一部分,不能被刪除。安全
也是鑑於上面幾個緣由,不提倡壓縮HTML,經過gzip壓縮就已經能達到很好的效果。
CSS壓縮合並
CSS壓縮合並很常見,或者說是必作的,能夠由後端動態生成或工具提早生成。目的也只是爲了提升加載速度,CSS即使的壓縮以後,代碼也是清晰可見,沒有混淆說法。CSS壓縮合並的工具不少,通常是用sass、less直接生成壓縮後的CSS,若是是直接壓縮,用grunt還不錯。
JS壓縮合並混淆
在生產環境上,壓縮合並是必作的。就如上面說的,目的不是爲了防止暴露業務邏輯,是爲了提升載入速度。在上一篇文章《AngularJS結合RequireJS作文件合併壓縮的那些坑》,說了一點JS壓縮合並要注意的東西。除了用RequireJS,直接使用grunt來作發佈是不錯的方式,開發後一鍵調用grunt。
grunt須要配置兩個文件:
package.json:聲明應用信息和使用依賴庫的版本
{ "name":"BingoTouch", "version":"3.0.0", "engines":{ "node":">= 0.8.0" }, "devDependencies":{ "grunt":"~0.4.0", "grunt-contrib-concat":"~0.3.0", "grunt-contrib-copy" : "~0.4.1", "grunt-contrib-cssmin" : "~0.6.0", "grunt-contrib-uglify":"~0.2.0", "express":"" } }
Gruntfile.js:聲明壓縮合並的文件
module.exports = function(grunt){ grunt.initConfig({ pkg : grunt.file.readJSON('package.json'), concat : { 'dist/bingotouch.js' : [ 'demo/js/ui.js', 'demo/js/module/ui.GarbageCollection.js', 'demo/js/module/ui.plugins.js'] }, uglify : { target : { files : { 'dist/bingotouch.min.js': 'dist/bingotouch.js' } } } }); grunt.loadNpmTasks('grunt-contrib-concat'); grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.registerTask('default', ['concat','uglify']); }
JS的混淆我到如今爲止還沒用過,原理都是相似的,混淆是把JS代碼變成亂七八糟的字符串,而後用eval執行。
PS:uglify自己有必定的混淆做用,但也只是對變量名的混淆,混淆度並不夠。
混淆前:
function hello(){ alert('hello'); }
混淆後:
eval(function(p,a,c,k,e,r){e=String;if(!''.replace(/^/,String)){while(c--)r[c]=k[c]||c;k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('1 0(){2(\'0\')}',3,3,'hello|function|alert'.split('|'),0,{}))
不一樣混淆算法混淆的結果不同,並且混淆後也不是一勞永逸,仍是能夠被反混淆的。另外混淆會下降程序執行性能,因此是否須要作混淆得作評估。
總結
我以爲作好文件壓縮合並,簡單的變量名混淆就能夠了,並不須要那麼完全的混淆。即使是前端被人挖得清清楚楚,只要後端強勁也就沒問題了。因此當你想進行代碼混淆時候,想一想是爲了什麼,值不值得。
另外咱們有時可能會作一些富前端的外包,那咱們在交付以前能夠對前端腳本進行加密,供演示使用。
1. 在代碼裏面設置一個代碼過時時間,過時後代碼就沒法使用了。
2. 對js進行壓縮混淆。
本文爲原創文章,轉載請保留原出處,方便溯源,若有錯誤地方,謝謝指正。