jwt登陆注册

jwt概念

token是不需要存储在数据库的,只需要后台生成密钥,当客户端发送过来请求时那么就把token塞在请求体或者头中,客户端接收到token时那么就存储在localStorage或者cookie中,注意这里不能把敏感信息进行token存储,要不然会被获取到(比如cookie中或者请求体中)并且进行反向解密从而暴露敏感信息,比如密码;
token中包含三块都是以

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9//头信息这个是固定写死的{'type': 'JWT','alg': 'HS256'}.> eyJ1c2VyIjoid2FuZyIsImVudmlyb25tZW50Ijoid2ViIiwiZXhwaXJlcyI6MTUzNTUyMDk1MTcxOX0//载体 就是比如客户端发过来的username.> 4rmP6UeeJ3mQbHfplruH15PvuUxPzFTxAfVnPgA7sgo//密钥根据将头和载体进行转换base64编码,然后在将头和载体根据sha256算法加密生成密钥(也就是第三步)这样就组成了一个token,将这种思路换成代码就会实现jwt-smilp包中的encode,那么decode就是获取到进行反向解码
jwt-smilp中的encode和decode
{username:username}//载体 载体中还可以设置时间以及其他 jwt.encode({username:username},sercet)//sercet自己定义的密钥 jwt.encode(token,sercet)//进行解密
登陆注册全过程

进入登陆页,输入账号和密码点击登陆请求接口,后台会在数据库中寻找对应的账号密码 如果存在那么后台会生成一个token并且塞在请求头(或者响应体中),给前端之后,前端获取返回值 并且存放在cookie中或者请求头中,前端通过axios中的请求拦截给请求头中塞进密钥,这样每次发送请求就会携带token,后台接收到token之后会进行解码校验是否是正确的token,如果是的话就进行下一步操作,如果不是的话就给前端提示

node后台代码的实现

将node框架搭好之后新建一个src的文件下新建一个app.js的文件代码如下

let express = require('express')let app = express()//获取req的bodylet bodyParser = require('body-parser');//引入自己写的登陆校验是否合规文件let retoken = require('./retoken/retoken.js')//bodyParser对应的以下两个也是解析post中的json数据app.use(express.json())//urlencoded解析x-ww-form-urlencoded请求体app.use(express.urlencoded())//返回的对象是一个键值对,当extended为false的时候,键值对中的值就为'String'或'Array'形式,为true的时候,则可为任何数据类型app.use(bodyParser.urlencoded({ extended: true }))//使用上面自己的写的中间件app.use(retoken)//登陆接口文件app.use('/login', require('./login/index.js'));//统一处理错误信息app.use((err, req, res, next) => {    if (err) {        res.status(500).json({            message: err.message        })    }})//默认监听3000端口app.listen(3000, () => {    console.log('服务启用成功');})
retoken.js
//使用第三方插件let jwt = require('jwt-simple');//定义加密和解密的密钥(随便写)const jstSecret = 'mengyuhang' function checkToken(req,res,next){ //判断如果是登陆接口或者注册接口那么就不需要校验token if(req.url!='/login/login'&&req.url!='/login/create'){ //这里前端是直接将token塞到了cookie中所以我直接在cookie中获取        let tokenClone = req.headers.cookie;//token传递过来的为这种形式:token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6Im15aDEyMyIsImV4cGlyZXMiOjE1OTQwNDU4NDc1NzN9.PwIAp3nXIscIvgXykjQumO6CbIFceHpGz6-2PUHgQU4//截取等号后面的        let token = tokenClone.split('=')[1]        if(token){        //如果存在那么解码,我这里加密的用户名和校验时间是否过期{ username: 'myh123', expires: 1594045847573 }            var decoded = jwt.decode(token, jstSecret)            //如果现在的时间超过了我设置的登陆时间那么就返回登陆过期            if(Date.now()>decoded.expires){                res.json({                    code:'-2',                    message: '登陆过期'                })            }else{            //否则向下执行              next()            }        }else{        //如果没有token那么返回提示            res.status(401).json({                code:"-1",                message: 'you need login:there is no token'            })        }    }else{    //如果为登陆或者注册接口直接向下进行        next()    }    }module.exports=checkToken
login.js中的接口书写
const express = require('express');let router = express.Router();//我这里使用sequelize操作数据库let sequelize = require('sequelize')let models = require('../../db/models')let jwt = require('jwt-simple');//设置token的过期时间const tokenExpiresTime = 1000 * 60 * 60 * 24 * 7//密钥const jstSecret = 'mengyuhang'router.post('/login', async (req, res, next) => {    let { username, password} = req.body;    try {    //在数据库中的user表中寻找对应的账号密码        let personalInformation = await models.User.findOne({            where: {                username,                password            }        })        //如果账号存在        if (personalInformation) {            //生成token            //需要加密的对象            let payload = {                username: personalInformation.username,                expires: Date.now() + tokenExpiresTime            }            //jwt-simple包提供的加密方法,jstSecret自己定义的密钥            let token = jwt.encode(payload, jstSecret)            res.json({                message: '登陆成功',                token            })        } else {        //如果账号不存在            res.json({                code: '-1',                message: '用户不存在,请校验信息是否正确'            })        }    } catch (e) {        res.json({            message: '错误'        })    }})//注册接口router.post('/create', async (req, res, next) => {    let { username, password } = req.body;    try{    //在数据库中寻找用户名        let user = await models.User.findOne({            where: {                username            }        })        //如果用户名存在        if (user) {            res.json({                code: '-1',                message: '用户名已存在'            })        } else {        //如果用户名不存在就可以注册成功啦            await models.User.create({                username,                password            })            res.json({                code: '0',                message: '注册成功'            })        }    }catch(e){next()    }    })module.exports = router

前端登陆

点击登陆时获取到后台返回的token之后直接塞在document.cookie中即可