前后端分離架構帶來的好處一搜一大堆藏古,我們來看一下分離后后端接口的安全問題蜂大。
前后端分離架構現(xiàn)狀:
前端:vue項目,Nginx部署
后端:node.js和java項目
這樣的情況后端api是暴露在外網中源譬,因為常規(guī)的web項目無論如何前端都是要通過公網訪問到后臺api的千贯,帶來的隱患也有很多。
1.接口公開送朱,誰都可以訪問
2.數(shù)據(jù)請求的參數(shù)在傳輸過程被篡改
3.接口被重復調用
...
session和cookie局限性
session和cookie都是客戶端與服務端通訊需要提供的認證娘荡,當客戶端的值和服務器的值吻合時,才允許請求api骤菠,解決了第1個問題它改,但是當攻擊者獲取到了傳輸過程中的session或者cookie值后,就可以進行第2商乎、3種攻擊了
JWT的token機制
JWT標準的token包含三部分:
1.header(頭部)央拖,頭部信息主要包括(參數(shù)的類型--JWT,簽名的算法--HS256)
2.poyload(負荷),負荷基本就是自己想要存放的信息(因為信息會暴露鹉戚,不應該在載荷里面加入任何敏感的數(shù)據(jù))鲜戒,有兩個形式,下邊會講到
3.sign(簽名)抹凳,簽名的作用就是為了防止惡意篡改數(shù)據(jù)
頭部(Header)
頭部用于描述關于該JWT的最基本的信息遏餐,例如其類型以及簽名所用的算法等
{
"typ": "JWT",
"alg": "HS256"
}
將上面的JSON對象進行[base64編碼]
可以得到下面的字符串。這個字符串我們將它稱作JWT的Header
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
載荷(Payload)
Payload也是一個JSON對象赢底。包含了一些其他的信息
{
"iss": "John Wu JWT",
"iat": 1441593502,
"exp": 1441594722,
"aud": "www.example.com",
"sub": "jrocket@example.com",
"from_user": "B",
"target_user": "A"
}
這里面的前五個字段都是由JWT的標準所定義的失都。
* `iss`: 該JWT的簽發(fā)者
* `sub`: 該JWT所面向的用戶
* `aud`: 接收該JWT的一方
* `exp`(expires): 什么時候過期柏蘑,這里是一個Unix時間戳
* `iat`(issued at): 在什么時候簽發(fā)的
將上面的JSON對象進行[base64編碼]
可以得到下面的字符串。這個字符串我們將它稱作JWT的Payload
eyJmcm9tX3VzZXIiOiJCIiwidGFyZ2V0X3VzZXIiOiJBIn0
注意:Base64是一種編碼粹庞,也就是說咳焚,它是可以被翻譯回原來的樣子來的。它并不是一種加密過程庞溜。
簽名(Sign)
將上面的兩個編碼后的字符串都用句號.
連接在一起(頭部在前)革半,就形成了
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmcm9tX3VzZXIiOiJCIiwidGFyZ2V0X3VzZXIiOiJBIn0
最后,我們將上面拼接完的字符串用HS256算法
進行加密流码。在加密的時候又官,我們還需要提供一個密鑰(secret)
。如果我們用mystar
作為密鑰的話漫试,那么就可以得到我們加密后的內容
rSWamyAYwuHCo7IFAgd1oRpSP7nzL7BF5t7ItqpKViM
這一部分叫做簽名
最后將這一部分簽名也拼接在被簽名的字符串后面六敬,我們就得到了完整的JWT
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmcm9tX3VzZXIiOiJCIiwidGFyZ2V0X3VzZXIiOiJBIn0.rSWamyAYwuHCo7IFAgd1oRpSP7nzL7BF5t7ItqpKViM
為什么要使用簽名
簽名解決了數(shù)據(jù)傳輸過程中參數(shù)被篡改的風險
一般而言,加密算法對于不同的輸入產生的輸出總是不一樣的商虐,如果有人對Header以及Payload的內容解碼之后進行修改觉阅,再進行編碼的話崖疤,那么新的頭部和載荷的簽名和之前的簽名就將是不一樣的秘车。而且,如果不知道服務器加密的時候用的密鑰的話劫哼,得出來的簽名也一定會是不一樣的叮趴。
服務器應用在接受到JWT后,會首先對頭部和載荷的內容用同一算法再次簽名权烧。如果服務器應用對頭部和載荷再次以同樣方法簽名之后發(fā)現(xiàn)眯亦,自己計算出來的簽名和接受到的簽名不一樣,那么就說明這個Token的內容被別人動過的般码,我們應該拒絕這個Token
如何防范Replay Attacks
解決了篡改數(shù)據(jù)的問題妻率,還有第3個問題,那就是攻擊者不修改數(shù)據(jù)板祝,只是重復攻擊
所謂重復攻擊就是攻擊者發(fā)送一個后端服務器已接收過的包宫静,來達到攻擊系統(tǒng)的目的。
比如在瀏覽器端通過用戶名/密碼驗證獲得簽名的Token被木馬竊取券时。即使用戶登出了系統(tǒng)孤里,黑客還是可以利用竊取的Token模擬正常請求,而服務器端對此完全不知道橘洞,因為JWT機制是無狀態(tài)的捌袜。
可以在Payload里增加時間戳并且前后端都參與來解決:
1.前端生成token時,在payload里增加當前時間戳
2.后端接收后炸枣,對解析出來的時間戳和當前時間進行判斷虏等,
3.如果相差特定時間內(比如2秒)弄唧,允許請求否則判定為重復攻擊