Express中的JWT使用

安装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


定义secret密钥

为了保证JWT字符串的安全性,防止jwt字符串传输的过程中别人破解,我们需要专门定义一个用于加密和解密的secret密钥:

  • 当生成JWT字符串的时候,需要使用secret密钥对用户的信息进行加密,最终得到加密好的JWT字符串
  • 当把JWT字符串解析还原成JSON对象的时候,需要对secret密钥进行解密(使用和前面加密相同的密钥)

如果定义:secret密钥的本质是一个字符串,所以定义字符串就可以

const secretKey=abdbdodjod-^-^-' 


如何在登录成功后生成JWT字符串——生成Token

        调用jsonwebtoken包中的sign()方法,将用户的信息加密生成JWT字符串,响应给客户端

sign({用户信息对象,密钥,配置对象(里面可配置expireIn:'30s' 指定token字符串的有效期)})

    //用户信息对象 密钥 有效期
    const tokenStr= jwt.sign(
    {username:req.body.username},secretKey,{expiresIn:'30'}//30=30秒 30h=30小时
    )

将JWT字符串还原成为JSON对象——解析Token

        客户端每次访问有权限的接口的时候,都需要主动通过请求头的Authorization字段,将Token字符串发送到服务器进行身份认证。此时我们调用express-jwt中间件,自动将客户端发送过来的Token解析还原成JSON对象:

app.use()注册中间件

expressJWT({secret:secretKey})         使用密钥解析Token的中间件

.unless({patn:[/^\/api\//]})         用来指定哪些接口不需要访问权限----正则表达式 /api开头的


使用req.user(req.auth)获取用户信息——有权限的接口

使用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  启动成功')
})

  

 

 


捕获解析JWT(即解析token)失败后产生的错误——错误中间件在最后 进行捕获错误

当使用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  启动成功')
})

 

  • 10
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值