Nodejs -- 一文学会如何在Express中使用JWT(json web token)

文章目录

  • 在Express中使用JWT
    • 1 安装JWT相关的包
    • 2 导入JWT相关的包
    • 3 定义secret密钥
    • 4 在登录成功后生成JWT字符串
    • 5 将JWT字符串还原为JSON对象
    • 6 使用req.user获取用户信息
    • 7 捕获解析JWT失败后产生的错误
    • 8 完整代码示例

在Express中使用JWT

1 安装JWT相关的包

运行如下命令,安装如下两个JWT相关的包:

npm install jsonwebtoken express-jwt

其中:

  • jsonwebtoken用于生成JWT字符串
  • express-jwt用于将JWT字符串解析还原成Json对像

2 导入JWT相关的包

//  1.导入用于生成JT字符串的包
const jwt = require('jsonwebtoken')

//2.导入用于将客户端发送过来的JwT字符串,解析还原成JS0N对象的包
const { expressjwt: jwt } = require("express-jwt");

3 定义secret密钥

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

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

密钥可以是任意的字符串,越复杂越好

//3.secret密钥的本质:就是一个字符串
const secretKey = 'Nodejs No1 ^_^'

4 在登录成功后生成JWT字符串

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

千万不要把密码加密到token中

//登录接口
app.post('/api/login', (req, res) => {
    // ··省略登录失败情况下的代码
	//用户登录成功之后,生成JWT字符串,通过token属性响应给客户端
    res.send({
        status: 200,
        message: '登录成功!',
		//调用jwt.sign()生成JWT字符串,三个参数分别是:用户信息对像、加密密钥、配置对橡
        token: jwt.sign({username: userinfo.username}, secretKey, {expiresIn: '30s'})
    })
})

完整代码:

const express = require("express")
const jwt = require("jsonwebtoken")
const {urlencoded} = require("express");

const app = express()
app.use(urlencoded({extended: false}))

const secretKey = "kkk *_*"

app.get("/login", (req, res) => {
    if (req.body.username === 'admin' && req.body.password === 'admin') {
        const tokenStr = jwt.sign({username: req.body.username}, secretKey, {expiresIn: "24h"})
        res.send({
            status: 200,
            msg: 'success',
            token: tokenStr
        })
    } else {
        req.send({
            msg: "账号或者密码错误"
        })
    }

})

app.listen(80, () => {
    console.log("server start")
})

启动后通过接口测试,得到结果如下:

Nodejs -- 一文学会如何在Express中使用JWT(json web token)_第1张图片

5 将JWT字符串还原为JSON对象

客户端海次在访问那些有权限接口的时候,都需要主动通过请求头中的Authorization字段,将Token字符串发送到服务器进行身份认证。

此时,服务器可以通过express-jwt这个中间件,自动将客户端发送过来的Token解析还原成json对像:

express-jwt7版本之后用法发生了变化,参考express-jwt - npm

const { expressjwt } = require("express-jwt");

// 使用app.use()来注册中间件
// .unless({path:[/^\/api\//]})用来指定哪些接口不需要访问权限
app.use(
    expressjwt({
        secret: secretKey,
        algorithms: ["HS256"]
  	}).unless({path: [/^\/api\//]})
)

6 使用req.user获取用户信息

express-jwt这个中间件配置成功之后,即可在那些有权限的接口中,使用req.user对象,来访问从JWT字符串中解析出来的用户信息了,示例代码如下:

只有配置好了express-jwt中间件之后才能通过req.user获取用户信息,

//这是一个有权限的API接口
app.get('/admin/getinfo', (req, res) => {
    console.log(re.user)
    res.send({
        status: 200,
        message: '获取用户信息成功!',
        data: req.auth
    })
})

7 捕获解析JWT失败后产生的错误

当使用express-jwt解析Token字符串时,如果客户端发送过来的Token字符串过期或不合法,会产生一个解析失败的错误,影响项目的正常运行。我们可以通过Express的错误中间件,捕获这个错误并进行相关的处理,示例代码如下:

记得放在最后

app.use((err, req, res, next) => {
    //token解析失败导致的错误
    if (err.name === 'UnauthorizedError') {
        return res.send({status: 401, message: '无效的token'})
    }

    //其它原因导致的错误
    res.send({status: 500, message: '未知错误'})
})

8 完整代码示例

const express = require("express")
const jwt = require("jsonwebtoken")
const {urlencoded} = require("express");
const {expressjwt} = require("express-jwt")

const app = express()
const secretKey = "kkk *_*"

app.use(urlencoded({extended: false}))

app.use(
    expressjwt({
        secret: secretKey,
        algorithms: ['HS256']
    }).unless({path: [/^\/api\//]})
)

app.get("/api/login", (req, res) => {
    if (req.body.username === 'admin' && req.body.password === 'admin') {
        const tokenStr = jwt.sign({username: req.body.username}, secretKey, {expiresIn: "24h"})
        res.send({
            status: 200,
            msg: 'success',
            token: tokenStr
        })
    } else {
        req.send({
            msg: "账号或者密码错误"
        })
    }
})

app.get("/user/getInfo", (req, res) => {
    res.send({
        status: 200,
        msg: "success",
        data: res.auth
    })
})

app.listen(80, () => {
    console.log("server start")
})

app.use((err, req, res, next) => {
    //token解析失败导致的错误
    if (err.name === 'UnauthorizedError') {
        return res.send({status: 401, message: '无效的token'})
    }

    //其它原因导致的错误
    res.send({status: 500, message: '未知错误'})
})

登录结果:

Nodejs -- 一文学会如何在Express中使用JWT(json web token)_第2张图片

获取信息成功结果:

记得将登陆中得到的token放到Authorization中,并且前面加上Bearer

Nodejs -- 一文学会如何在Express中使用JWT(json web token)_第3张图片

token有误的情况:

Nodejs -- 一文学会如何在Express中使用JWT(json web token)_第4张图片

你可能感兴趣的:(#,Node.js,json,前端,express,node.js)