nestjs项目实战,前端用nuxt,构建一个简单的用户管理系统,包括传输加解密,密码存储加密,权限控制

本文介绍了如何使用Nuxt3、Vue3、VantUI库、Nest.js框架以及MySQL数据库,搭建一个包括用户管理、权限控制和登录功能的简单系统。作者详细描述了配置服务器、创建Nest项目、模块化开发、数据库操作和安全性措施的过程。
摘要由CSDN通过智能技术生成

之前本来是想把学习用的nest测试项目部署上去实现增删改查已经联表查询功能试试的,但是想想既然已经部署到服务端并且能正常运行了,那本地跟服务端差别不大了,还不如搞个真正的需求部署上去,所以今天想自己用nuxt3+vue3+vant4+nestjs+mysql实现一个简单的人员管理系统

首先第一步:阿里云服务器实例转配

之前选了按量付费,一天要五块多,太心疼了,转包月先

正式开始:

1、新建nest项目

在我们想要新建nest项目的目录下打开命令行工具运行以下命令

nest new project-name

为了让我们的请求地址看起来正规一点,我们这里加上一个统一的前缀吧

main.ts

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.setGlobalPrefix('manager')
  await app.listen(3000);
}

 2、新建user模块

src目录下运行以下命令

 nest g res user

出现选项选第一个跟Y就行了,它们自动把你新建的模块引入到app主模块中去

src目录下已经有user模块并且在app.module中自动引入了

3、启动nestjs项目

要加dev,才有热更新

npm run start:dev

 报了个错:

因为这个端口之前有个工程正在用着,那我们先把这个工程关掉吧,暂时用不着,重新启动,出现以下这些表示成功了

访问一下:localhost:3000

找不到地址,因为我们之前设置了全局的前缀manager,加上

成功

我们先来构建一个用户的实体吧,一个用户拥有哪些基本数据:

用户名,不能重复,昵称(可选),密码,创建时间,最后一次登录时间,角色(用于控制权限,后面需要新建权限表),id(自增),用户状态(枚举值),deleted(用于软删除,新建时默认为否),token数组,因为考虑到多端登录情况,暂时想到这些,后面可以再加,其实还想搞个头像功能的,但是考虑到还要专门搞个文件服务器,还是先不搞了

过程:

1、新建user,token实体

2、在app.module中引入TypeOrmModule连接数据库

3、在user.module中引入TypeOrmModule并放入user,token实体

4、在user.service中引入两张库表,用来对对应表进行增删改查操作

都保存完之后数据库中已经出现这两张表了

新增用户接口写好之后调一下接口(中间具体过程不细讲,看完nestjs教程基本上就知道怎么搞了)

成功了,再看下数据库中数据,有了

 为了后面删除操作,我们多搞了几条测试数据

自己把增删改查搞定了,中间过程省略,这里默认你们是会nest的,后续等我熟悉了nest可以考虑再仔细讲讲,现在自己也是个初学者状态

4、新建nuxt3前端工程

npx nuxi@latest init <project-name>

后面很多活都可以交给tongyilingma了,比如你直接跟他说,我要用某某组件(例:element-plus,甚至可以带上具体版本号)写一个后台管理页面,或者写一个表格,表格里面有哪些内容,写一个弹窗,弹窗里面有哪些内容,然后copy到页面里面,改写数据,就差不多了,看下效果

增删改查都写好了,增删改查的弹窗都可以交给tongyilingma然后自己稍微改改调接口就行 

经测试增删改查功能都没问题,接着我们既然要模拟真实应用,就要对后端应用进行改良

5、登录

登录方法给用户发token,数组存储,但是我们这里暂时只允许存在一个token 

jwt依赖自己安装:

npm i jsonwebtoken


const jwt = require('jsonwebtoken');

 调用login方法,搞定

token校验,校验通过返回用户信息即可:

async checkToken(token: string) {
    try {
      const decoded = jwt.verify(token, secretKey);
      console.log('checktoken decoded ', decoded.userId)
      if (decoded.userId) { // 验证通过,返回用户信息
        const user = await this.usersRespository.findOne({
          where:
            { id: decoded.userId }
        });
        console.log('checktoken user ', user)
        return user
      }
      return decoded;
    } catch (err) {
      console.log('checkToken err ', err)
      return null;
    }
  }

6、密码加解密 

  1. 前后端传输加密,这里用我们常用的aes(对称加解密),这一步搞了好久,篇幅较长,重起一片文章写这个了:前端cryptojs加解密,后端node环境(nestjs)crypto加解密
  2. 数据库存储密码加密,我们肯定不能直接前端加密密码传输然后后端直接将前端aes加密后的密码字段存在数据库,因为我们知道对称加密前后端秘钥一致,且这个秘钥是很容易搞到的,所以如果直接存前端传过来的加密密码方案肯定不可行,而且一般前后端加密传输一般都是针对整个请求对象加解密,一般不止针对密码加密
  • 所以这里我们用nestjs推荐的bcypt
    npm i bcrypt
    npm i -D @types/bcrypt
  •     存储密码前加密
  • user.password = await bcrypt.hash(user.password, config.pwdSaltOrRounds)

    调用添加方法,再查看数据库:

可以看到,数据已经被加密了

这时候我们能想到,之前登录方法里面的用户名密码对比肯定走不通了,bcrypt提供了对比方法,因为我们给user的实体中的password设置了select:false,是无法查询到的,所以这里要加select才能查出来

调用一下登录方法,成功

注意要在我们搞完加解密之后调接口新产生的数据,才是有做数据库存储加解密的数据

让我们输个错误密码试下,没问题

在这里说一下,不要用前端传入密码用bcrypt加密然后跟数据库存储的密码去做对比,因为每次机密产生的字符串都是不一样的,结果永远是false,要用bcrypt提供的同步对比方法 

bcrypt.compareSync(password, res[0].password)

 7、权限控制

这是最后一步,作为管理系统,用户的增删改查肯定不是所有用户都有权限操作,所以我们要加一个权限控制,所以我们要在加一个用户角色表

每个用户暂时只能有一个角色吧,一对一

每个路由前面加个权限判断

if (headers.token) {
      const hasPermission = await this.userService.hasPermission(PermissionCode.ADD, headers.token)
      if (hasPermission) {
        return await this.userService.create(createUserDto);
      } else {
        return { message: '没有添加用户权限' };
      }
    } else {
      return {
        message: '没有添加用户权限'
      }
    }

权限判断

async hasPermission(permission: PermissionCode, token: string): Promise<boolean> {
    if (!permission || !token) {
      return false
    }
    const adminPermissions = [PermissionCode.ADD, PermissionCode.DELETE, PermissionCode.UPDATE, PermissionCode.QUERY]
    const operatorPermissions = [PermissionCode.ADD, PermissionCode.QUERY]
    const userPermissions = [PermissionCode.QUERY]
    const user = await this.checkToken(token)
    console.log('hasPermission user ', user)
    if (user && user.roles && user.roles.code) {
      if (user.roles.code === RoleCode.ADMIN && adminPermissions.includes(permission)) {
        return true
      }
      if (user.roles.code === RoleCode.Operator && operatorPermissions.includes(permission)) {
        return true
      }
      if (user.roles.code === RoleCode.USER && userPermissions.includes(permission)) {
        return true
      }
    }

    return false
  }

首先,未登录状态下试下

 没问题,让我们登录管理员再试下,添加成功

这里面用到的登录就是常规的,登录完之后得到token,把token放在缓存里面,在请求的时候把token放在请求头里面,服务端拿这个token去做校验,校验通过拿到用户信息及用户角色信息,根据角色信息判断是否有改权限,从而继续后面的操作

到这里一个简单的用户管理系统就基本完成了,看到这里的是默认会nest的,所以中间很多nest的基础部分就没有细讲了 

  • 15
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值