這裏要用到三個插件, 加上前端一共是至少4個插件前端
>>>>>>後端應用:
jsonwebtoken //生成token字符串
passport //token解析主插件
passport-jwt // 密鑰解析規則插件, 有密鑰解析
------------------------------------------------------------
>>>>>> 給前端使用的
jwt-decode //無密鑰解析, secretOrKey 是存儲在環境變量中的,所以在前端必須使用無密鑰解析。
複製代碼
// jwt加密的使用:
const jwt = require('jsonwebtoken');
// 無密鑰解析插件
const jwt_decode = require('jwt-decode');
//設置一個密鑰
const secretOrKey = "hello world";
//待生成token的對象
const rules = { id: '0001', name: 'liyuanzhe', job: 'developer' };
// -----> 這裏使用promise 方便你們分開查看這兩個插件的執行
new Promise((resolve, require) => {
// jwt.sign是異步執行操做
// 使用jsonwebtoken建立字符串
// 參數 (須要加密的內容, 密鑰字符串, token屬性, 回調函數)
jwt.sign(rules, secretOrKey, { expiresIn: 3600 }, (err, token) => {
if (err) throw err;
token = "Bearer " + token /*根據插件做者的要求, 這裏必定要寫 Bearer空格*/
console.log(token);
// 打印生成的token字符串
//Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjAwMDEiLCJuYW1lIjoibGl5dWFuemhlI iwiam9iIjoiZGV2ZWxvcGVyIiwiaWF0IjoxNTU3Mzk3ODYwLCJleHAiOjE1NTc0MDE0NjB9.fT4eKuvAbvH66QM frSHEm1UmeHPedYOWYIr3rNwAPg8
// res.send(token) 實際開發發送給前端
resolve(token);
});
}).then((token) => {
//shiyong jwt-decode 對token 進行無密鑰解析
console.log(jwt_decode(token));
//輸出結果:
// { id: '0001', name: 'liyuanzhe', job: 'developer',
// iat: 1557397860, exp: 1557401460 }
// iat : 生效時間
// exp :過時時間
//前端拿到這個字符串後應當進行解析, 而後進行localstorage,sessionStorage存儲,
//發送網絡請求時,再把token字符串再發給後端,
})
複製代碼
passport //token解析主插件 至關於各類passport策略的容器web
passport-jwt // 密鑰解析規則(策略)插件, 有密鑰解析算法
接下來以這個爲例:數據庫
// /*
// passport有策略(strategy)的概念. strategy是少許預定義的方法,
// 它們會在請求抵達真正的路由以前執行.假如你定義的strategy認定某個請求非法,
// 則該路由不會被執行, 而是返回401 Unauthorized.
// */
const express = require('express');
const server = express();
//使用body解析中間件
const bodyParser = require('body-parser');
server.use(bodyParser.urlencoded({ extended: false }));
server.use(bodyParser.json());
server.listen(8080);
const router = express.Router(); //引入路由 ,以後發起網絡請求作判斷
//引入passport插件
const passport = require('passport');
//對passpor進行初始化
server.use(passport.initialize());
// jwt策略函數
const JwtStrategy = require('passport-jwt').Strategy;
// 抽取jwt函數
const ExtractJwt = require('passport-jwt').ExtractJwt;
//設置策略選項 1. 密鑰 2.抽取token的方法
let opts = {
// 存入環境變量的混淆密鑰
secretOrKey: "hello world",
// 定義從請求頭的Authrization抽取token數據
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken()
}
// 構造 策略對象
var jwtConfig = new JwtStrategy(opts, (jwt_payload, next) => {
// jwt_payload 解析好的 token字符串,
// 和 jwt-decode 解析的同樣, 可是這個會進行密鑰的判斷
// 若是密鑰匹配失敗, 直接結束返回401狀態碼
console.log(jwt_payload)
//這個在實戰開發中會有和數據庫中id查找
// DB_User.findById(jwt_payload.id){
// .then(user => {
// return done(null, user)
// }).catch(err => {
// console.log(err)
// })
// }
//爲了測試咱們就無腦下一步了
next(null, jwt_payload)
});
// 應用在passport中
passport.use(jwtConfig);
// passport.authenticate("加密算法策略", 驗證條件,回調)
router.get('/testJWT', passport.authenticate("jwt", { session: false }), (req, res) => {
res.json({ ok: 1 })
})
server.use('/test', router);
複製代碼
測試:express
{ id: '0001', name: 'liyuanzhe', job: 'developer'}json
Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjAwMDEiLCJuYW1lIjoibGl5dWFuemhlIiwiam9iIjoiZGV2ZWxvcGVyIiwiaWF0IjoxNTU3NDA0NzE1LCJleHAiOjE1NTc0MDgzMTV9.jqwwdAH4qKFCX7t0xHJ0YXiprNmlSpM0sDc8PwoWSbc後端
{ id: '0001', name: 'liyuanzhe', job: 'developer', iat: 1557404715, exp: 1557408315 }promise
輸入有效的token: bash
server passport passport-jwt 三者之間的關係網絡
三層嵌套use
// 建立解析規則部分
server.use (
passport.use(
new passport-jwt.Strategy(
//策略選項
{secretOrKey: "hello world",jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken()},
//回調函數
(jwt_payload, next)=>{
next(null, jwt_payload)
}
)
)
)
// ------> 使用部分
// passport.authenticate("jwt", 驗證條件,回調)
router.get('/testJWT', passport.authenticate("jwt", { session: false }), (req, res) => {
res.json({ ok: 1 })
})
server.use('/test', router);
複製代碼