解析jsonwebtoken(jwt)在nodejs中的使用。

這裏要用到三個插件, 加上前端一共是至少4個插件前端

>>>>>>後端應用:
jsonwebtoken //生成token字符串

passport //token解析主插件

passport-jwt // 密鑰解析規則插件, 有密鑰解析
------------------------------------------------------------

>>>>>> 給前端使用的
jwt-decode   //無密鑰解析, secretOrKey 是存儲在環境變量中的,所以在前端必須使用無密鑰解析。

複製代碼

使用jsonwebtoken進行加密 和 使用jwt無密鑰解析

// 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字符串再發給後端,
    
    
})
複製代碼

後端對發送給前端的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

前端生成token :

Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjAwMDEiLCJuYW1lIjoibGl5dWFuemhlIiwiam9iIjoiZGV2ZWxvcGVyIiwiaWF0IjoxNTU3NDA0NzE1LCJleHAiOjE1NTc0MDgzMTV9.jqwwdAH4qKFCX7t0xHJ0YXiprNmlSpM0sDc8PwoWSbc後端

使用jwt-decode 解析token:

{ id: '0001', name: 'liyuanzhe', job: 'developer', iat: 1557404715, exp: 1557408315 }promise

使用postman測試

輸入有效的token: bash

輸入過時的token:

總結:

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);
複製代碼
相關文章
相關標籤/搜索