node:<10>jwt 加密机制

jwt加密是一种简单的加密,虽说是加密,但是建议大家不要将自己的密码放在jwt加密的行列,因为会导致泄露,jwt有加密就有解密,我们需要用到两个模块,express-jwt jsonwebtoken ;

先来了解一下到底jwt是什么,其实就是一种字符串,只是有Header.Payload.Signature三部分组成的,不过只有Payload存储的使我们的信息数据,其他两部分是jwt用来加密的机制,可以有效的防止别人破解;

接下来就是如何实现这个加密:

1、导入安装模块:

npm i express-jwt jsonwebtoken 
//2.2 安装并导入jwt模块
const expressjwt = require('express-jwt')//模块作用就是将jwt字符串还原成json字符串
const jsontoken = require('jsonwebtoken')//模块作用就是将json字符串加密成一个jwt对象

同样,我们是在服务器上对客户端提供的账户密码进行处理,我们就拿用户名来加密好了,之前我们学过如果创建服务器和如何提交表单,如果不记得可以去前面看;

2、在加密的过程之中,我们需要一个秘钥,这个秘钥本质就是一个字符串,一个自定义字符串,越复杂越难让别人破解,所以我们先定义好一个比较复杂秘钥:

//2.1 创建一个秘钥用来加密
const secretkey = 'tonysecret^_^'

3、 加密需要用到jsonwebtoken模块的sign()方法,这个方法有三个参数,第一个是我们要加密的对象,注意是一个对象,不是一个字符串,然后第二个是我们定义的秘钥,第三个是我们的有效期,也是一个对象,我们的信息对象可以用客户端提交过来的表单数据req

 //2.4 创建一个token对象
 const mytoken = jsontoken.sign({username:req.body.username},secretkey,{expiresIn:'1h'})

我这里用到了提交表单里面的用户名,然后有效期是一个小时;

4、当然,我们加密之后就需要解密,也就是当我们客户端拿到服务器给的token时候,可以发一个带有Authorization响应头的请求,这样就可以拿到我们的用户名:

            const mytoken = jsontoken.sign({username:req.body.username},secretkey,{expiresIn:'1h'})
            //2.5 将加密的jwt返回给客户端
            res.send({
                status:200,
                message:'登陆成功',
                username:mytoken
            })

当我们加密之后,客户端会拿到一个字符串是jwt类型,也就是Header.Payload.Signature类型:

这就是我们拿到的username,经过了加密处理变成了jwt格式,如果我们要解密,就可以发起一个get请求,这个请求就带有这个token的,也就是username后面的这一串字符串,

 可以看到,我们在postman里面发起带有这个响应头的get请求我们可以拿到经过解析的对象;还有一个要注意,在我们填响应头数据的时候需要在我门token前面加一个Bearer空格,不然的话请求不会成功,key的话就是我们的Authorization类型。

5、关于服务器放对带有token的响应头的解码,因为这个响应头其实就携带这这个username的信息,所以我们解码之后就可以拿到,我们需要用到express-jet模块,使用下面的方法可以解析jwt字符串并且将解析出来的对象挂载到req上,对象名为user所以我们可以通过res.send()直接将req.user发送给客户端,那么客户端就可以拿到这个信息了:

//3.2 注册一个全局中间件对jwt进行解析
app.use(expressjwt({secret:secretkey,algorithms:['HS256']}).unless({path:[/^\/api\//]}))

//3.1 注册一个get路由,用来获取我们加密的对象
app.get('/admin/logininfo',(req,res)=>{
    console.log(req.user)
    res.send({
        status:200,
        message:'获取信息成功',
        username:req.user
    })
})

 expressjwt()方法的参数就是我们的秘钥,是一个对象要注意,对象的属性有我们的秘钥,当然在express-jwt6.0版本之后我们要加上后面algorithms:['HS256']这句话,不然会报一个algroithms未定义的错误,这是固定写法所以还是加上,而unless()这个方法只是不需要权限访问,里面也是一个对象,一个含有path属性的对象,path属性是一个数组,里面可以用正则表达式来筛选哪一些请求不需要访问权限,我这里是筛选api接口不需要权限;注意我们的解码放在我们的get路由前面就可以了,如果放在太前会出现解析问题,因为我们还没有加密就解析的话会出错、

6、为了保证安全运行,我们需要在后面添加一个错误捕获路由,还记得吗,我们之前讲过专门捕获错误的路由:

//4.1 注册一个中间件路由将错误捕获
app.use((err,req,res,next)=>{
    if(err.name == 'UnauthorizedError'){
        return res.send({
            status:401,
            message:'无效token'
        })
    }
    res.send({
        status:401,
        message:'其他错误'
    })
})

这个路由很简单,如果我们错误名字为UnauthorizedError就说明是一个解析错误的问题,也就是起到一个分析是否是解析错误的错误捕获路由;

回顾我们之前的session认证机制,相比之下我们的jwt要更加流行,因为jwt弥补了session不嫩跨域访问的问题,而且我们在学习中可以发现,我们加密的数据会到达客户端,也就是存在了客户端,而服务器就起到一个加密和解密的作用。

好了,这一期就到这里;

下面我分享所有代码:

//1.1 安装并导入模块
const express = require('express')
const session = require('express-session')
//2.2 安装并导入jwt模块
const expressjwt = require('express-jwt')//模块作用就是将jwt字符串还原成json字符串
const jsontoken = require('jsonwebtoken')//模块作用就是将json字符串加密成一个jwt对象


//1.2 创建一个服务器
const app = express()

//1.3 使用编码中间件
app.use(express.urlencoded({extended:false}))

//2.1 创建一个秘钥用来加密
const secretkey = 'tonysecret^_^'



//2.3 注册一个post路由
app.post('/admin/login',(req,res)=>{
    if(req.body.username == 'tony' && req.body.password == '000000'){
            //2.4 创建一个token对象
            const mytoken = jsontoken.sign({username:req.body.username},secretkey,{expiresIn:'1h'})
            //2.5 将加密的jwt返回给客户端
            res.send({
                status:200,
                message:'登陆成功',
                username:mytoken
            })
    }else{
        res.send({
            status:401,
            message:'登录失败'
        })
     
    }

})

//3.2 注册一个全局中间件对jwt进行解析
app.use(expressjwt({secret:secretkey,algorithms:['HS256']}).unless({path:[/^\/api\//]}))

//3.1 注册一个get路由,用来获取我们加密的对象
app.get('/admin/logininfo',(req,res)=>{
    console.log(req.user)
    res.send({
        status:200,
        message:'获取信息成功',
        username:req.user
    })
})




//4.1 注册一个中间件路由将错误捕获
app.use((err,req,res,next)=>{
    if(err.name == 'UnauthorizedError'){
        return res.send({
            status:401,
            message:'无效token'
        })
    }
    res.send({
        status:401,
        message:'其他错误'
    })
})

//1.4 打开服务器
app.listen(8080,()=>{
    console.log('server  running at http://127.0.0.1:8080')
})

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编程学渣ズ

谢谢老板

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值