❤Nodejs 第十章(用户信息token认证和登录接口开发)

411 阅读5分钟

❤Nodejs 第十章(用户信息token登录使用和开发)

1、安装

jsonwebtoken

比较官方的称呼为JSON Web Token(JWT),一种开放标准(RFC 7519),就类似砸门认知的w3c,主要就是更安全地传输信息。利用数字签名验证数据的完整性和身份。

所以JWT 通常用于验证身份和安全的交换信息,是一种轻量级、安全且可扩展的身份验证机制,大概被分为以下几种:

  1. 用户身份验证:用户登录后,服务器生成一个 JWT 返回给客户端,客户端在请求中携带该 JWT,服务器通过验证 JWT 的签名来确认用户的身份。(就是咋们网站必须登录才能访问某个网页)
  2. 信息交换:在微服务架构中传输一些需要身份验证和授权的安全和完整信息。
  3. 声明传输:JWT 中包含一些声明(claim),例如可以安全传输和验证用户的身份信息、权限等,不需要在每次请求中查询数据库。
  4. 单点登录:JWT 可以被用来实现单点登录(SSO),用户只需要登录一次,就可以访问多个关联的系统。

express

用于构建 Rest API 帮助前后端实现通讯

express模块 用于构建 Rest API 帮助前后端通讯API和Web应用程序的一个轻量级的Node.js框架,换句话说,我们想要在后端创造接口让前端去访问,就需要用到它。

简化了在Node.js上构建Web应用程序的过程,提供了路由、中间件、模板引擎等功能,简单方便还丰富!

Express的主要作用包括:

1、路由:允许我们定义和处理各种HTTP请求方法(GET、POST、PUT、DELETE等。根据不同的URL路径和HTTP请求方法定义处理函数,实现请求的路由分发。 2、中间件:允许我们在处理HTTP请求之前或之后自定义操作。中间件可以处理身份验证、日志记录、错误处理等。 3、模板引擎:Express支持EJS、Pug等,使我们将动态内容嵌入到静态页面中。实现页面的动态渲染。 4、 静态文件服务: 提供静态文件的服务,例如图片、CSS、JavaScript文件等。将静态文件存储在指定的目录中,进行访问和加载。 5、 RESTful API支持: 借助路由和中间件构建RESTful API,实现对数据的CRUD操作,构建API服务。

安装jsonwebtoken和express-jwt第三方包

yarn add jsonwebtoken express-jwt --save

2、创建一个基本的服务器

//导入express
const express = require('express')
 
//创建服务器对象
const app = express()
 
//启动服务器
app.listen(8888,function(){
    console.log('express server running at http://127.0.0.1:8888')
})

3、导入 jsonwebtoken 和 express-jwt 第三方包

//身份认证部分包
import jwt from 'jsonwebtoken' // 1.导入jsonwebtoken生成 jwt 字符串的包
import expressJWT  from 'express-jwt' // 2.导入将客户端发送过来的 JWT 字符串,解析还原成 JSON 对象的包
  

4、创建一个密钥

const secretKey = 'aflowerdemon is No1 ^_^' //密钥里边的字符可以自定义

注册将客户端发送过来的 jwt 字符串,解析还原成 JSON 对象的中间件 express-jwt 注意:

1.这边将jwt字符串解析出来的信息会被挂载到req.user属性上,可以通过req.user属性获取到信息。

2.下边的unless({path[]})中是不需要 token访问权限的路径。

3. 这边注意一下,你的登录请求路径,放一定在unless({path[]})中,让它无需token权限,否则你会一直请求失败(这个坑我踩过)如下边代码所示:

5、定义接口认证和接口白名单

path之中是不需要进行token认证的接口

// token认证
app.use(
  expressJWT.expressjwt({ secret: secretKey, algorithms: ["HS256"] }).unless({
    // path: [/^\/api\//],
    path: [
            '/',
            '/api/login',
            '/api/register',
            '/api/resetPwd'
     ]
  })
);

接下来我们尝试访问用户接口

image.png

告诉我们没有授权访问信息

image.png

我们简单写一个白名单中的登录接口如下:

// 用户登录接口
app.post('/api/login', (req, res) => {
    let query = 'SELECT * FROM user';
    connectionpool.query(query, (err, results) => {
        console.log(err,'err');
        console.log(results,'results');
        if (err) {
            console.error('Error querying database:', err);
            res.status(500).json({ error: 'Internal server error' });
            return;
        }
        res.json({
            code: '200',
            data: results ? results[0] : {},
        });
    });
});

访问一下试试

返回的结果如下图所示:可以看出我们的接口可以正常访问

image.png

不在白名单的接口是无法进行访问的,访问就是未授权!

5、登录接口

接下来我们利用登录接口返回我们的token认证,我们做一个简单的模拟


// 用户登录接口
app.post('/api/login', (req, res) => {
    let query = 'SELECT * FROM user';

     // 登录失败
    if (req.body.username !== 'admin' && req.body.password !== '123456') {
      return res.send({
        status: '400',
        message: '登录失败'
      })
    }
    // 登录成功
    // 格式:jwt.sign({用户信息},密钥,token有效时长)
    var tokenStr = jwt.sign({ username: req.body.username }, secretKey, { expiresIn: '2h' })
    res.send({
      status: 200,
      message: '登录成功',
      token: tokenStr
    })
});

整个流程是这样子的:

请求接口,开始认证是否在白名单中
在白名单中,进行账号密码判断
失败=》返回信息
正确=》 jwt注册账号名,然后加密以后返回token

当我们输入正确的账号密码时:

image.png

错误时:

image.png

这里遇到了一下小问题,写的判断居然市失效了,最后清理了一下缓存,重新优化一下判断

// 用户登录接口
app.post('/api/login', (req, res) => {
    // let query = 'SELECT * FROM user';
    console.log(req.body,'req');
    console.log(req.body.username == 'admin');
    console.log(req.body.password == '123456');
    if (req.body.username == 'admin' && req.body.password == '123456') {
      // 登录成功
      console.log(111);
        // 先制作jwt字符串 记住千万不要把密码加密到 token 字符串中,这样容易被人破解密码
        // 格式:jwt.sign({用户信息},密钥,token有效时长)
        var tokenStr = jwt.sign({ username: req.body.username }, secretKey, { expiresIn: '2h' })
        res.send({
          status: 200,
          message: '登录成功',
          token: tokenStr
        })
    }else{
       // 登录失败
       console.log(222);
       res.send({
        status: '400',
        message: '登录失败'
      })
    }
});

ok! 问题成功解决!