当前位置: 首页 > 后端技术 > Node.js

jwt登录验证携带token

时间:2023-04-03 10:34:42 Node.js

jwt登录注册jwt概念token不需要存储在数据库中,只需要在后台生成一个key,当客户端发送请求时,然后将token放在请求体或header中,当客户端收到token时,然后存储在localStorage或cookie中,注意这里token中不能存储敏感信息,否则会被获取(如cookie或requestbody中)并反向解密,暴露敏感信息,如密码;tokencontainsthreepieces以eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9//头信息这个是固定写死的{'type':'JWT','alg':'HS256'}.>eyJ1c2VyIjoid2FuZyIsImVudmlyb25tZW50Ijoid2ViIiwiZXhwaXJlcyI6MTUzNTUyMDk1MTcxOX0//载体就是比如客户端发过来的username.>4rmP6UeeJ3mQbHfplruH15PvuUxPzFTxAfVnPgA7sgo//密匙将header和carrier转为base64编码,然后根据sha256算法对header和carrier进行加密,生成key(也就是第三步),这样就形成了token。把这个思路改成代码会实现jwt-smilp包中的Encode,然后decode就是获取jwt-smilp中的encode和decode进行反解码{username:username}//载体也可以设置时间等jwt.encode({username:username},sercet)//sercet定义的keyjwt.encode(token,sercet)//解密登录注册全过程进入登录页面,输入账号和密码点击登录请求接口,后台会在数据库中查找对应的账号密码,如果存在则后台会生成一个token,塞入请求头(或响应体)中。交给前端后,前端获取返回值,存入cookie或请求头中。前端拦截axios中的请求,将key插入到请求头中,这样每次发送请求时,都会携带token。后台收到token后,会解码验证是否是正确的token。如果是,请继续下一步。框架搭建完成后,新建一个src文件,新建一个app.js文件代码如接下来letexpress=require('express')letapp=express()//获取reqbodyParser=require('body-parser');//引入自己写的登录验证文件letretoken=require('./retoken/retoken.js')//bodyParser对应下面两个也是解析post中的json数据app.use(express.json())//urlencoded解析x-ww-form-urlencodedrequestbodyapp.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//使用第三方插件letjwt=require('jwt-simple');//定义加解密的key(随便写)constjstSecret='mengyuhang'functioncheckToken(req,res,next){//判断是登录界面还是注册界面不需要验证tokenif(req.url!='/login/login'&&req.url!='/login/create'){//这里前端直接把token塞进cookie中所以我直接在cookie中获取lettokenClone=req.headers.cookie;//token传递过来的为这种形式:token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6Im15aDEyMyIsImV4cGlyZXMiOjE1OTQwNDU4NDc1NzN9.PwIAp3nXIscIvgXykjQumO6CbIFceHpGz6-2PUHgQU4//截取等号后面的lettoken=tokenClone.split('=')[1]if(token){//Ifitexists,thendecodeit,whethermyencryptedusernameandverificationtimehaveexpired{username:'myh123',expires:1594045847573}vardecoded=jwt.decode(token,jstSecret)//IfthecurrenttimeexceedsthelogintimeIset,thenreturntheloginexpirationif(Date.now()>decoded.expires){res.json({code:'-2',message:'Loginexpired'})}else{//Otherwiseexecutenext()downward}}else{//Ifthereisnotoken,thenreturnapromptres.status(401).json({code:"-1",message:'youneedlogin:thereisnotoken'})}}else{//Ifitisloginorregistrationinterface,godirectlytonext()}}module.exports=checkTokenlogin.js中的接口是这样写的constexpress=require('express');letrouter=express.Router();//我这里使用sequelize来操作数据库letsequelize=require('sequelize')letmodels=require('../../db/models')letjwt=require('jwt-simple');//设置token的过期时间consttokenExpiresTime=1000*60*60*24*7//KeyconstjstSecret='mengyuhang'router.post('/login',async(req,res,next)=>{let{username,password}=req.body;try{//在user表中找到对应的账号密码thedatabaseletpersonalInformation=awaitmodels.User.findOne({where:{username,password}})//如果账户存在if(personalInformation){//生成token//需要加密的对象letpayload={username:personalInformation.username,expires:Date.now()+tokenExpiresTime}//jwt-simple包提供的加密方式,jstSecret自己定义的keylettoken=jwt.encode(payload,jstSecret)res.json({message:'登录成功',token})}else{//如果账号不存在res.json({code:'-1',message:'用户不存在,请检查信息是否正确'})}}catch(e){res.json({message:'error'})}})//注册接口router.post('/create',async(req,res,next)=>{let{username,password}=req.body;try{//在数据库中查找用户名letuser=awaitmodels.User.findOne({where:{username}})//如果用户名存在if(user){res.json({code:'-1',message:'用户名已经存在'})}else{//如果用户名不存在,注册成功awaitmodels.User.create({username,password})res.json({code:'0',message:'注册成功'})}}catch(e){next()}})module.exports=路由器前端登录Lu点击登录的时候,拿到后台返回的token,然后直接塞到document.cookie里面