4.4 權限攔截控制\AccessToken jwt-博客後端Api-NodeJs+Express+Mysql實戰

權限控制

業務需求:查看用戶列表接口(管理員才能使用)、更新用戶信息接口(當前對應用戶才能調用)

這時候須要須要加入中間件來實現權限控制:html

clipboard.png

這時候我們須要學習瞭解下 :AccessToken jwt前端

AccessToken jwt

課前學習瞭解
JSON Web Token 入門教程
http://www.ruanyifeng.com/blo...
基於jsonwebtoken(JWT) 的web認證 (Node版實現)
https://segmentfault.com/a/11...
node-jsonwebtoken
https://github.com/auth0/node...

本文中使用了node-jsonwebtoken@7.2.1插件node

clipboard.png

clipboard.png

現將token服務邏輯代碼附上git

/**
 * token服務
 * add by boomer 2019-05-03 21:57:11
 */
var Promise = require("bluebird");
var config = require('config-lite'); //配置
var jwt = require('jsonwebtoken'); //json token

module.exports = {
    /**
     * 設置token 建立token
     */
    setToken: function(payload) {
        // var expiresIn = Math.floor(Date.now() / 1000) + (1 * 60); // var expiresIn = '24h';
        var expiresIn = Date.now() + 3600000 * 24;//24小時後
        var token = jwt.sign(payload, config.token.secretOrPrivateKey, {
            expiresIn: expiresIn, // 設置過時時間
        });
        return {
            token: token,
            expiresIn: expiresIn,
        };
    },
    /**
     * 驗證token是否正確:傳入當前token和當前用戶uuid
     */
    verifyToken: function(token, userUuid){
        return new Promise(function(resolve, reject) {
            jwt.verify(token, config.token.secretOrPrivateKey, function(err, tokenData) {
                if (tokenData && tokenData.uuid == userUuid) {
                    resolve('ok');
                }else{
                    reject('fail');
                }
            });
        });
    },
    /**
     * 路由驗證token
     */
    verifyRouterToken: function(req, res, next, isAdmin) {
        //accesstoken 被自動轉小寫了
        var token = req.headers.accesstoken;
        if (!token) { // 若是沒有token,則返回錯誤
            res.json({
                code: "401",
            });
            return;
        } else { //驗證token
            jwt.verify(token, config.token.secretOrPrivateKey, function(err, tokenData) { //只有在token正確時tokenData有值
                if (err) {
                    res.json({
                        code: "402",
                    });
                    return;
                } else {
                    //驗證是否爲管理員
                    if (isAdmin && !tokenData.isAdmin) {
                        res.json({
                            code: "403",
                        });
                        return;
                    } else if (!isAdmin && tokenData.uuid && !tokenData.isAdmin) {
                        //驗證userUuid 避免普通用戶登陸修改其餘人資料
                        var userUuid = (req.body || req.query || req.params)['userUuid'];
                        if (userUuid && userUuid != tokenData.uuid) {
                            res.json({
                                code: "403",
                            });
                            return;
                        } else {
                            next();
                        }
                    } else {
                        next();
                    }
                }
            });
        }
    },
    /**
     * 清除token
     */
    delToken: function(token) {
        if (!token) {
            return 'delTokenFail';
        } else {
            jwt.decode(token);
            return 'delTokenSuccess';
        }
    },
};

accessToken通常在登陸/註冊成功時獲取 而後緩存到本地,每次前端請求時將有效的accessToken放到headers中(這塊後面寫前端時補充 更新token心跳機制等),而後請求到後端,後端再經過校驗token中間件作權限攔截,校驗經過後才能執行後面的業務邏輯
如今說下,後端經過上面tokenService.setToken方法 生成AccessToken的代碼:
clipboard.pnggithub

相關文章
相關標籤/搜索