Node JS通过jwt设置token
token(身份令牌),其实就是用加密算法加密少量用户信息,以及记录创建时间与其他少量配置项,聚合而成的一个字符串。
如果你的服务端只有登陆时需要验证,之后都处于无信任状态——譬如用户权限、路由等信息都存储在客户端缓存内,那token就没必要了;
如果需要进行验证,那token就能很好的完成这个任务了。
token需要每次请求都要发送,因此考虑将其生成后,放置在请求拦截器中
const Axios = axios.create({ baseURL: baseUrl,// 后台服务地址,这里是开发所以改为本机,后面发布后要改地址为8.188 timeout: 15000, // 请求超时时间1分钟 responseType: "json", withCredentials: false, // 是否允许带cookie这些 }); Axios.interceptors.request.use(config => { const token = JSON.parse(sessionStorage.getItem("token")) // 若是没有token以及设置了跳过token——登录——则不设置 if (token?.token && !config.headers?.skipToken) { config.headers['Authorization'] = `Bearer ${token.token}` } return config }, (error => { console.log(error) // 错误请求的处理 return Promise.reject(error) }))
登陆时因为没有token,所以跳过这一步。之后有的,就在请求头中的属性“Authorization”中设置,这是约定俗成的token字段;
Bearer:这是翻译当前token采用的类型,但一般后端服务器也是协商好的用同种类型,所以这里是可以省略该部分,直接加上服务器传递过来的token字符串
后端部分,需要注意的是,若是提示“Authorization”或者“skiptoken”存在跨域问题,无法访问后端接口的话,请在后端加上这部分
//nodejs let express = require('express') let app = express() //添加中间件,自动解析请求内容 app.all('*', function (req, res, next) { res.header('Access-Control-Allow-Origin', '*') res.header('Access-Control-Allow-Headers', 'content-type,Authorization,skipToken') res.header('Access-Control-Allow-Methods', 'DELETE,PUT,POST,GET,OPTIONS') if (req.method.toLowerCase() === 'options') res.sendStatus(200) else next() })
这是nodejs的解决跨域方式,其他语言请自行查找。
生成token部分:
const jwt = require('jsonwebtoken')
const secret = 'RicardoX3' //自定义密钥 const token = jwt.sign({username: req.body.userName, password: req.body.UserPwd}, secret, {expiresIn: 3600 * 24}) //过期时间为24小时,基础时间为秒
接着继续添加中间件进行拦截,注意,请确保这些都在所有请求接口上面,因为nodejs是从上往下去对照的
app.use(function (req, res, next) { if (!req.headers.skiptoken) { const token = jwt.decode(req.headers?.authorization.slice(7)) //超过24小时则发送令牌过期信息 if (new Date().getTime() - token.exp * 1000 > 0 || token.iat * 1000 - new Date().getTime() > 0) { res.sendStatus(424) } else next() } else next() })
需要注意的是,jwt的时间戳是以秒为单位的,所以要计算的时候记得带上1000转换为毫秒。
jwt.sign第一个部分为你要加密的部分,第二个为加密密钥,第三个为自定义配置项;官网给的解码是分为三部分(当然密文也是3部分,xxxx.yyyy.zzzz);
第一部分是加密算法,这部分默认的;
第二部分是加密的内容,这部分解码后会自带token创建时间——即使你没在配置里加上这个——以及自定义配置项内的部分标签(譬如过期时间);
第三部分为加密密钥。
但从给的sign()方法看来,其官网演示的参数似乎不是很明确?譬如文档里就没有"expiresIn"这个参数,但是你必须得在sign里放在第三个参数内才生效,解码时会变成exp,就挺奇怪的……
如果你自己写了个加密算法的话,那也可以不用jwt;
后端在调用登录接口时顺带将生成的token发送给前端,让其存储在缓存中即可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义