作用是什么
express-jwt是nodejs的一個中間件,他來驗證指定http請求的JsonWebTokens的有效性,如果有效就將JsonWebTokens的值設(shè)置到req.user里面,然后路由到相應(yīng)的router。 此模塊允許您使用Node.js應(yīng)用程序中的JWT令牌來驗證HTTP請求。 JWT通常用于保護API端點。
express-jwt和jsonwebtoken是什么關(guān)系
express-jwt內(nèi)部引用了jsonwebtoken,對其封裝使用。 在實際的項目中這兩個都需要引用,他們兩個的定位不一樣。jsonwebtoken是用來生成token給客戶端的,express-jwt是用來驗證token的。
如何使用
安裝
npm install express-jwt
設(shè)置需要保護的API
var expressJWT = require('express-jwt');
var secretOrPrivateKey = "hello BigManing" //加密token 校驗token時要使用
app.use(expressJWT({
secret: secretOrPrivateKey
}).unless({
path: ['/getToken'] //除了這個地址,其他的URL都需要驗證
}));
校驗token失敗時的處理
app.use(function (err, req, res, next) {
if (err.name === 'UnauthorizedError') {
// 這個需要根據(jù)自己的業(yè)務(wù)邏輯來處理( 具體的err值 請看下面)
res.status(401).send('invalid token...');
}
});
- token過期時的err值
{
"name": "UnauthorizedError",
"message": "jwt expired",
"code": "invalid_token",
"status": 401,
"inner": {
"name": "TokenExpiredError",
"message": "jwt expired",
"expiredAt": "2017-08-03T10:08:44.000Z"
}
}
- token無效時的err值:
{
"name": "UnauthorizedError",
"message": "invalid signature",
"code": "invalid_token",
"status": 401,
"inner": {
"name": "JsonWebTokenError",
"message": "invalid signature"
}
}
定義返回給客戶端token的接口
var jwt = require('jsonwebtoken');
// 何時返回token 要根據(jù)自己的業(yè)務(wù)邏輯
app.get('/getToken', function (req, res) {
res.json({
result: 'ok',
token: jwt.sign({
name: "BinMaing",
data: "============="
}, secretOrPrivateKey, {
expiresIn: 60 * 1
})
})
});
帶著token訪問/getData接口
// 訪問這個地址 , token 要放到 authorization 這個header里,
// 對應(yīng)的值以Bearer開頭然后空一格,接近著是token值。為什么會這樣,請看下面后續(xù)。
app.get('/getData', function (req, res) {
res.send(req.user)
});
查看返回的結(jié)果:
{
"name": "BinMaing",
"data": "=============",
"iat": 1501814188,
"exp": 1501814248
}
客戶端攜帶token正確的姿勢
authorization:Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiQmluTWFpbmciLCJkYXRhIjoiPT09PT09PT09PT09PSIsImlhdCI6MTUwMTgxNDE4OCwiZXhwIjoxNTAxODE0MjQ4fQ.GoxGlc6E02W5VvqDNawaOrj3MPO-4UYeFdngKR4bVTE
為什么會這樣攜帶token,請看express-jwt源碼里是如何獲取token的:
//1 從options中獲取token 這個忽略 因為 在設(shè)置 需要保護的API 時 并沒有傳遞 getToken 這個方法
if (options.getToken && typeof options.getToken === 'function') {
try {
token = options.getToken(req);
} catch (e) {
return next(e);
}
//2 從authorization中獲取token
} else if (req.headers && req.headers.authorization) {
// --這是關(guān)鍵代碼-----開始切割--------->
var parts = req.headers.authorization.split(' ');
if (parts.length == 2) {
var scheme = parts[0];
var credentials = parts[1];
if (/^Bearer$/i.test(scheme)) {
token = credentials; // <-------最終獲取到token---------
} else {
if (credentialsRequired) {
return next(new UnauthorizedError('credentials_bad_scheme', { message: 'Format is Authorization: Bearer [token]' }));
} else {
return next();
}
}
//3 以上兩個途徑都沒有token時 就報錯唄
} else {
return next(new UnauthorizedError('credentials_bad_format', { message: 'Format is Authorization: Bearer [token]' }));
}
}
總體流程:

express-jwt 作為中間件都做了什么