node使用jwt生成token

使用jwt生成token

JSON Web Token(JWT)是目前最流行的跨域身份驗證解決方案。

  • 1、引入jsonwebtoken
var jwt = require('jsonwebtoken');
  • 2、生成一個token
// 生成一個token
const secret = 'yating';
function makeToken(name, password, exp) {
    return token = jwt.sign({ name, password, exp }, secret);
}
類似這樣的:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoidGluZ2VyIiwicGFzc3dvcmQiOiJndW93ZWkiLCJleHAiOjE1Njc0MTQ1NjEsImlhdCI6MTU2NzQxMjc2MX0.75ARiai6NXo0UrqMyW30eumfAz4zNzqfZT0nm85LlFk

具體的原理什麼的,請請大家自己去網上找一下,我也講的不是很清楚。

  • 3、驗證token是否過期,我這裏用了一個promis方法,沒有過期的時候,decoded會返回token的解析結果。
// 驗證token
function verifyToken(token) {
    return new Promise((reslove, reject) => {
        jwt.verify(token, secret, (err, decoded) => {
            if (err) {
                // 驗證過期失敗
                reject(err);
            } else {
                // 驗證成功傳用戶信息
                reslove(decoded)
            }
        })
    })
}
  • 4、再次之前要比對一下存在數據庫裏的用戶是否存在與請求的token一致
// 對比數據庫裏的token
function verifyMysqlToken(token, userName) {
    return new Promise((reslove, reject) => {
        // 只要token和用戶名爲空,name就失敗
        if(token==undefined||userName==undefined){
            reject();
        }else{
            // 1、先在數據庫裏比對token
            var sql = `select token from users where user='${userName}'; `
            mysqlPool(sql).then(data => {
                // 如果請求的token跟存在數據庫裏的token一直,name就驗證是否過期;
                var mysqlToken = data[0].token
                console.log(mysqlToken == token,"對比結果")
                if (mysqlToken == token) {
                    console.log("請求的token跟數據庫裏的token一致")
                    // 開始驗證,調用驗證函數,成功後調用reslove的方法,失敗就reject()
                    verifyToken(token).then(data => reslove(data)).catch(err => reject())
                } else {
                    // 不一致,則結束;
                    console.log("不一致")
                    reject()
                }
            })
        }
    })
}
  • 5、以後涉及用到權限的時候都套用這個方式,其中1、2我已經合在verifyMysqlToken方法裏了。

1、對比一下請求的token是否與數據庫裏的token一致,不一致則結束;

2、一致,則驗證一下token是否過期。過期則結束;

3、token沒有過期,則有權限操作。

//下面跟權限有關的接口都要套上這個格式
 var ifok = verifyMysqlToken(req.headers.token, req.headers.username);
    ifok.then(data => {
//有權限操作的代碼,對數據庫進行操作
    }).catch(err => {
//無權限操作的代碼,不對數據庫操作
    });
  • 6、當用戶登錄成功時,與數據庫裏的賬號跟密碼進行比對。然後就開始生成token,並且設置一下過期時間,這裏我設置的是3分鐘。返回給前端。
// 登錄
router.post('/login', function (req, res, next) {
    var user = req.body.user;
    var password = req.body.password;
    var sql = `select * from users where user='${user}' and password='${password}'; `
    mysqlPool(sql)
        .then((data) => {
            if (data.length == 1) {
                var expTime = Math.floor(Date.now() / 1000) + 60 * 3;//過期時間1分鐘
                var token = makeToken(user, password, expTime);//生成token
                // 將token存到數據庫裏
                var sqlsaveToken = `UPDATE users SET token="${token}"where user='${user}' and password='${password}';`
                mysqlPool(sqlsaveToken).then(data => { console.log("更新用戶token") }).catch(err => { console.log("更新失敗") });
                // 返回token給前端
                var message = {
                    token:token,
                    info: "登錄成功~",
                    code: 1
                }
                res.send(message);
            } else {
                var message = {
                    info: "不存在用戶~",
                    code: 0
                }
                res.send(message);
            }
        })
        .catch((err) => {
            var message = {
                info: "請求錯誤!",
                code: -1
            }
            res.send(message)
        })
});
  • 7、舉個例子:
// 刪除
router.post('/delete', function (req, res, next) {
    var ifok = verifyMysqlToken(req.headers.token, req.headers.username);
    // 有權限則可以操作:
    ifok.then(data => {
        var tableName = req.body.tableName;
        var id = req.body.id;
        var sql = `DELETE FROM ${tableName} WHERE id=${id};`
        mysqlPool(sql)
            .then((data) => {
                var message = {
                    info: "刪除成功~",
                    code: 1
                }
                res.send(message);
            })
            .catch((err) => {
                var message = {
                    info: "刪除失敗",
                    code: 0
                }
                res.send(message)
            })
    }).catch(() => {
        var message = {
            info: "你沒有權限操作o(´^`)o~",
            code: -1
        }
        res.send(message)
    });
});
  • 8、前端獲得token以後要存在session裏。然後每次請求的時候,把token放在header裏。
function POST(url, params) {
    return new Promise((scuessful, fail) => {
        var userInfo = sessionStorage.getItem('userInfo');
        if(userInfo){
            axios.defaults.headers.token = JSON.parse(userInfo).token;
            axios.defaults.headers.userName = JSON.parse(userInfo).userName;
        }
        axios.post(url, params)
            .then(function (response) {
                scuessful(response);
            })
            .catch(function (error) {
                fail(error);
            });
    });
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章