在nodejs中实现token机制

token实际是一种身份验证机制,用来防御CSRF攻击。大致的流程是这样的:

  • 用户输入账号密码,前端进行加密处理后传给后端。后端进行验证。
  • 如果验证通过,后端返回一个token作为用户的身份认证令牌给前端。
  • 前端将token存储起来,使用cookie或者localstorage都可以。
  • 每次进行请求,都将token放在Header中,后端获取到token之后进行验证:如果token过期,后端返回401错误。如果token没有过期,执行后续操作。

下面通过node来实践一下token的机制。

如何创建一个token?

利用jsonwebtoken进行token的创建与验证。

const jwt = require("jsonwebtoken");
const SECRET = "QWERTYUIOPasdfghjklZXCVBNM"
...
jwt.sign(data, SECRET, {
    expiresIn: '7 days'
})

详细参考npm官方文档:https://www.npmjs.com/package/jsonwebtoken

如何验证一个token?

const jwt = require("jsonwebtoken");
...
jwt.verify(token, SECRET, (err, decode)={
    if(err){
        // token失效
    }else {
    	const data = decode; // decode即为创建token时使用的data数据	
	}
})

如何做到退出登录后token失效?

思路:在user用户表中添加一个isvalid字段,作为用户的权限字段。

当用户注册的时候,isvalid为0;当用户登录的时候,将isvalid置1;退出登录的时候,将isvalid重新设置为0。

通过判断token是否过期之后,判断isvalid的值,来决定是否进行下一步。

如何判断用户是否有权限?

思路:在验证token是否失效(或者无效之后),再判断isvalid的值。

// 验证token -- 返回token验证的结果 -- 返回一个promise
let verifyToken = (req)=>{
    return new Promise((resolve, reject)=>{
        let token = req.headers.authorization;
        if(token){
            let tokenArr = token.split("");
            tokenArr.pop();
            tokenArr.shift();
            token = tokenArr.join("");

            // 验证:只有当token可解,同时isvalid的值有效的时候,才能通过验证。
            jwt.verify(token, SECRET, (err, decode)=>{
                if(err){
                    resolve(false);
                }else {
                    const id = decode.id;
                    sql(`select isvalid from user where id=${id}`).then(data=>{
                        if(data[0]["isvalid"] == 0){
                            resolve(false);
                        }else{
                            const data = { id }
                            resolve(data);
                        }
                    })
                }
            })
        }else {
            return false
        }
    })
}

用一个promise来封装,以便后续操作。比如一个getUserInfo接口:

router.get("/getUserInfo", (req, res)=>{
    verifyToken(req).then(data=>{
        if(data){
            const id = data["id"];
            sql(`select id,username from user where id=${id}`).then(data=>{
                res.status(200).send(Object.assign(data, { message: "success" }))
            }).catch(err=>{
                console.log("获取用户信息失败");
                res.status(500).send({
                    message: "fail"
                })
            })
        }else{
            res.status(401).send({
                message:"fail"
            })
        }
    })
})

你可能感兴趣的:(node,token,node.js,javascript,vue.js)