Session認證機制中需要配合cookie才能實現,由于cookie默認不支持跨域訪問,當涉及到前端跨域請求后端接口時,需要做很多額外的配置,才能實現跨域session認證。所以這里不推薦使用session身份認證機制,一般推薦使用jwt認證。
目錄
一、JWT的概念
二、JWT工作原理
?三、JWT的組成部分
四、JWT的使用方式
五、在express中使用JWT
1.安裝JWT相關的包
2.導入JWT相關的包
3.定義secret密鑰
4.在登錄成功后生成jwt字符串
5.將jwt字符串還原為JSON對象
?6.使用req.user獲取用戶信息
一、JWT的概念
JWT(英文全稱:JSON Web Token)是目前最流行的跨域認證解決方案。
二、JWT工作原理
用戶的信息通過token字符串的形式,保存在客戶端瀏覽器中,服務器通過還原token字符串的形式來認證用戶的身份。
?三、JWT的組成部分
jwt通常由三部分組成,分別是header(頭部)、payload(有效荷載)、signature(簽名),三者之間使用英文的“.”分隔,格式如下:
header.payload.signature
payload | 是真正的用戶信息,它是用戶信息經過加密之后生成的字符串 |
header、signature | 是安全性相關的部分,只是為了保證token的安全性 |
四、JWT的使用方式
客戶端收到服務器返回的JWT之后,通常會將它儲存在 localStorage 或 sessionStorage 中,此后,客戶端每次與服務器通信,都要帶上這個JWT 的字符串,從而進行身份認證。推薦的做法是把 JWT 放在 HTTP請求頭的 Authorization 字段中格式如下:
Authorization:Bearer<token>
五、在express中使用JWT
1.安裝JWT相關的包
運行如下命令,安裝如下兩個JWT相關的包:
npm i jsonwebtoken express-jwt
jsonwebtoken:用于生成JWT字符串;
express-jwt:用于將JWT字符串解析還原成JSON對象。
2.導入JWT相關的包
使用require()函數,分別導入JWT相關的兩個包:
//導入用于生成jwt字符串的包
const jwt = require('jsonwebtoken')
//導入用于將客戶端發送過來的jwt字符串,解析還原成JSON對象的包
const expressJwt = require('express-jwt')
3.定義secret密鑰
為了保證jwt字符串的安全性,防止jwt字符串在網絡傳輸中被別人破解,我們需要專門定義一個用于加密和解密的secret密鑰:
- 當生成jwt字符串的時候,需要使用secret密鑰對用戶信息進行加密,最終得到加密好的jwt字符串;
- 當把jwt字符串解析還原成JSON對象的時候,需要使用secret密鑰進行解密;
//設置密鑰
const secret = '123456'
4.在登錄成功后生成jwt字符串
調用jsonwebtoken包提供的sign()方法,將用戶的信息加密成jwt字符串,響應給客戶端:
//登錄接口
app.post('/api/login', (req, res) => { //省略登錄失敗情況下的代碼//用戶登錄成功之后,生成jwt字符串,通過token屬性響應給客戶端res.send({code: 200,message: 'success',//調用jwt.sign方法生成token字符串token:jwt.sign({username:userinfo.username}, secret, {expiresIn: '1h'})})
})
5.將jwt字符串還原為JSON對象
?客戶端每次在訪問那些有權限接口的時候,都需要主動通過請求頭中的 Authorization 字段,將 Token 字符串發送到服務器進行身份認證。此時,服務器可以通過 express-jwt 這個中間件,自動將客戶端發送過來的 Token 解析還原成 JSON 對象:
//使用app.use()來注冊中間件
//expressJwt({secret: secret})就是用來解析token的中間件
//.unless({path:[/^\/api\//]})用來指定那些接口不需要那些接口不需要訪問權限
app.use(expressJwt({secret: secret}).unless({path:[/^\/api\//]}))
?6.使用req.user獲取用戶信息
當express-jwt這個中間件配置成功之后,即可在哪些有權限的接口中,使用req.user對象,來訪問從jwt字符串中解析出來的用戶信息了,示例代碼如下:
//這是一個有權限的接口
app.get('/api/protected', (req, res) => { //使用req.auth獲取用戶信息,并使用data屬性將用戶信息發送給客戶端res.send({code: 200,message: 'success',data: req.auth})
})