安装jwt相关的包两个:jsonwebtoken \ express-jwt
jsonwebtoken :作用生成JWT字符串(在服务器中将用户的信息转成JWT字符串)
express-jwt:将JWT字符串解析还原成JSON对象(从客户端保留的JWT加密字段 使用此包将用户的信息还原成真正的用户信息)
首先 新建文件夹:然后运行npm init -y 生成 package.json
之后安装需要的包 npm i jsonwebtoken 和 npm i express-jwt——全部需要的包
安装包使用空格将所有与的包进行分隔开 一起导入
- const jwt=require('jsonwebtoken')//生成JWT
- const expressJWT=require('express-jwt')//解析JWT
为了保证JWT字符串的安全性,防止jwt字符串传输的过程中别人破解,我们需要专门定义一个用于加密和解密的secret密钥:
如果定义:secret密钥的本质是一个字符串,所以定义字符串就可以
const secretKey=abdbdodjod-^-^-'
调用jsonwebtoken包中的sign()方法,将用户的信息加密生成JWT字符串,响应给客户端
sign({用户信息对象,密钥,配置对象(里面可配置expireIn:'30s' 指定token字符串的有效期)})
- //用户信息对象 密钥 有效期
- const tokenStr= jwt.sign(
- {username:req.body.username},secretKey,{expiresIn:'30'}//30=30秒 30h=30小时
- )
客户端每次访问有权限的接口的时候,都需要主动通过请求头的Authorization字段,将Token字符串发送到服务器进行身份认证。此时我们调用express-jwt中间件,自动将客户端发送过来的Token解析还原成JSON对象:
app.use()注册中间件
expressJWT({secret:secretKey}) 使用密钥解析Token的中间件
.unless({patn:[/^\/api\//]}) 用来指定哪些接口不需要访问权限----正则表达式 /api开头的
使用express-jwt这个中间件配置成功后,即可在那些有权限的接口中,使用req.user对象,来访问JWT字符串中解析出来的用户信息——正常情况下,req里面是没有属性的,当配置解析token的中间件完成后,会自动将解析出来的用户信息挂载到req.user上————express-jwt - npm
查看最新文档
安装的第三方包
app.js(登录成功之后加密用户的信息对象——为了保证安全性 不要将密码进行加密——
//HS256 使用同一个「secret_key」进行签名与验证
//RS256 是使用 RSA 私钥进行签名,使用 RSA 公钥进行验证。
)
注意发送响应头的时候需要加上Bearer空格
-
- //导入express模块
- const express=require('express')
-
- //创建web服务器
- const app=express()
- const jwt=require('jsonwebtoken')//生成JWT
- var { expressjwt: expressJWT } = require("express-jwt");//解析JWT
-
- //解决接口跨域问题
- const cors=require('cors')
- app.use(cors())
- //配置解析表单数据的中间件 POST请求
- app.use(express.urlencoded({extended:false}))
- //定义secret密钥
- const secretKey='--234--'
- //挂载路由
- //HS256 使用同一个「secret_key」进行签名与验证
- //RS256 是使用 RSA 私钥进行签名,使用 RSA 公钥进行验证。
- app.use( expressJWT({secret:secretKey,algorithms: ["HS256"]}).unless({path:[/^\/api\//]}))// /匹配的内容/ ^不在\转义/api/
-
- app.post('/api/login',(req,res)=>{
- //判断用户提交的登录信息是否正确
- if(req.body.username !=='admin'||req.body.password!=='0000'){
- return res.send(
- {status:400,msg:'登录失败'}
- )//服务器发送给客户端
- }
- //登录成功之后加密用户的信息对象——为了保证安全性 不要将密码进行加密
- //否则token泄露 你的密码也泄露了
- //用户信息对象 密钥 有效期
- const tokenStr= jwt.sign(
- {username:req.body.username,a:req.body.hello},secretKey,{expiresIn:'1h'}//30=30ms 30h=30小时 我设置的比较长 为了防止我使用get命令太慢了
- )
- //登录成功生成jwt字符串
- res.send({status:202,
- msg:'登录成功',
- token:tokenStr,//要发送给客户端的token字符串
- })//服务器发送给客户端状态
-
- })
- //有权限
- app.get('/admin/getinfo',(req,res)=>{
- console.log(req.auth)
- res.send({
- status:200,
- message:'获取用户信息成功',
- data:req.auth,//要发送给客户端的用户信息
- })
- })
- //启动服务器、使用80端口
- app.listen(8888,()=>{
- console.log('http://127.0.0.1:8888 启动成功')
- })
当使用express-jwt解析Token字符串时,如果客户端发送过来的Token字符串过期或不合法,会产生一个解析失败的错误,影响项目的正常运行,可以通过Express的错误中间件,捕获这个错误并进行相关的处理
app.use---err.name==UnauthorizeError——Token解析失败
- //全局中间件
- app.use(function (err, req, res, next) {
- if (err.name === "UnauthorizedError") {
- res.send({
- status:401,
- message:'无效的Token',
-
- })
- }
- res.send({
- status:500,
- message:'未知的错误',
- }
- )
- });
-
- //导入express模块
- const express=require('express')
-
- //创建web服务器
- const app=express()
- const jwt=require('jsonwebtoken')//生成JWT
- var { expressjwt: expressJWT } = require("express-jwt");//解析JWT
-
- //解决接口跨域问题
- const cors=require('cors')
- app.use(cors())
- //配置解析表单数据的中间件 POST请求
- app.use(express.urlencoded({extended:false}))
- //定义secret密钥
- const secretKey='--234--'
- //挂载路由
- //HS256 使用同一个「secret_key」进行签名与验证
- //RS256 是使用 RSA 私钥进行签名,使用 RSA 公钥进行验证。
- app.use( expressJWT({secret:secretKey,algorithms: ["HS256"]}).unless({path:[/^\/api\//]}))// /匹配的内容/ ^不在\转义/api/
-
- app.post('/api/login',(req,res)=>{
- //判断用户提交的登录信息是否正确
- if(req.body.username !=='admin'||req.body.password!=='0000'){
- return res.send(
- {status:400,msg:'登录失败'}
- )//服务器发送给客户端
- }
- //登录成功之后加密用户的信息对象——为了保证安全性 不要将密码进行加密
- //否则token泄露 你的密码也泄露了
- //用户信息对象 密钥 有效期
- const tokenStr= jwt.sign(
- {username:req.body.username,a:req.body.hello},secretKey,{expiresIn:'60s'}//30=30ms 30h=30小时 我设置的比较长 为了防止我使用get命令太慢了
- )
- //登录成功生成jwt字符串
- res.send({status:202,
- msg:'登录成功',
- token:tokenStr,//要发送给客户端的token字符串
- })//服务器发送给客户端状态
-
- })
- //有权限
- app.get('/admin/getinfo',(req,res)=>{
- console.log(req.auth)
- res.send({
- status:200,
- message:'获取用户信息成功',
- data:req.auth,//要发送给客户端的用户信息
- })
- })
- //全局中间件
- app.use(function (err, req, res, next) {
- if (err.name === "UnauthorizedError") {
- res.send({
- status:401,
- message:'无效的Token',
-
- })
- }
- res.send({
- status:500,
- message:'未知的错误',
- }
- )
- });
- //启动服务器、使用80端口
- app.listen(8888,()=>{
- console.log('http://127.0.0.1:8888 启动成功')
- })