Nest.js 实战系列第二篇-实现注册、扫码登陆、jwt认证等

大厂技术  高级前端  Node进阶

点击上方 程序员成长指北,关注公众号

回复1,加入高级Node交流群

大家好我是考拉🐨,这是 Nest.js 实战系列第二篇,我要用最真实的场景让你学会使用 Node 主流框架。

先对最近催更的几个小伙伴,说一句 sorry,最近工作中 Node 后端内容做的不多,一直在做 低代码平台 相关,所以延迟了一些,不知道截图中这个小伙伴还关注我没,嘻嘻🐨,你若还在便是铁粉无疑了!

3733d4eddbf479281a3762cc04a4d284.png

上一篇中 【Nest.js入门之基本项目搭建】 带大家入门了Nest.js, 接下来在之前的代码上继续进行开发, 主要两个任务:实现用户的注册与登录。

在实现登录注册之前,需要先整理一下需求, 我们希望用户有两种方式可以登录进入网站来写文章, 一种是账号密码登录,另一种是微信扫码登录。文章内容大纲

75de46546c24f04c9a18972186f16a12.png

接着上章内容开始...

前面我们创建文件都是一个个创建的, 其实还有一个快速创建ContollerServiceModule以及DTO文件的方式:

nest g resouce user
b84761b0d8923b84e67a581fb2cf52ff.gif

这样我们就快速的创建了一个REST API的模块,里面简单的CRUD代码都已经实现了,哈哈,发现我们前面一章学习的一半的内容,可以一句命令就搞定~

用户注册

在注册功能中,当用户是通过用户名和密码进行注册,密码我们不能直接存明文在数据库中,所以采用bcryptjs实现加密, 然后再存入数据库。

实现注册之前,先了解一下加密方案bcryptjs,安装一下依赖包:

npm install bcryptjs

bcryptjs 是nodejs中比较好的一款加盐(salt)加密的包, 我们处理密码加密、校验要使用到的两个方法:

/**
 * 加密处理 - 同步方法
 * bcryptjs.hashSync(data, salt)
 *    - data  要加密的数据
 *    - slat  用于哈希密码的盐。如果指定为数字,则将使用指定的轮数生成盐并将其使用。推荐 10
 */
const hashPassword = bcryptjs.hashSync(password, 10)


/**
 * 校验 - 使用同步方法
 * bcryptjs.compareSync(data, encrypted)
 *    - data        要比较的数据, 使用登录时传递过来的密码
 *    - encrypted   要比较的数据, 使用从数据库中查询出来的加密过的密码
 */
const isOk = bcryptjs.compareSync(password, encryptPassword)

接下来设计用户实体:

// use/entities/user.entity.ts
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';

@Entity('user')
export class User {
  @PrimaryGeneratedColumn('uuid')
  id: number;

  @Column({ length: 100 })
  username: string; // 用户名

  @Column({ length: 100 })
  nickname: string;  //昵称

  @Column()
  password: string;  // 密码

  @Column()
  avatar: string;   //头像

  @Column()
  email: string;

  @Column('simple-enum', { enum: ['root', 'author', 'visitor'] })
  role: string;   // 用户角色

  @Column({
    name: 'create_time',
    type: 'timestamp',
    default: () => 'CURRENT_TIMESTAMP',
  })
  createTime: Date;

  @Column({
    name: 'update_time',
    type: 'timestamp',
    default: () => 'CURRENT_TIMESTAMP',
  })
  updateTime: Date;
  
  @BeforeInsert() 
  async encryptPwd() { 
    this.password = await bcrypt.hashSync(this.password); 
  } 
}
  1. 在创建User实体, 使用@PrimaryGeneratedColumn('uuid')创建一个主列id,该值将使用uuid自动生成。Uuid 是一个独特的字符串;

  2. 实现字段名驼峰转下划线命名, createTimeupdateTime字段转为下划线命名方式存入数据库, 只需要在@Column装饰器中指定name属性;

  3. 我们使用了装饰器@BeforeInsert来装饰encryptPwd方法,表示该方法在数据插入之前调用,这样就能保证插入数据库的密码都是加密后的。

  4. 给博客系统设置了三种角色rootautorvisitor, root有所以权限,author有写文章权限,visitor只能阅读文章, 注册的用户默认是visitor,root权限的账号可以修改用户角色。

接下来实现注册用户的业务逻辑

register 注册用户

实现user.service.ts逻辑:

import { User } from './entities/user.entity';
import { Injectable, HttpException, HttpStatus } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { CreateUserDto } from './dto/create-user.dto';
import { Repository } from 'typeorm';

@Injectable()
export class UserService {
  constructor(
    @InjectRepository(User)
    private userRepository: Repository<User>,
  ) {}
  async register(createUser: CreateUserDto) {
    const { username } = createUser;

    const existUser = await this.userRepository.findOne({
      where: { username },
    });
    if(existUser){
        throw new HttpException("用户名已存在", HttpStatus.BAD_REQUEST)
    }

    const newUser = await this.userRepository.create(createUser)
    return await this.userRepository.save(newUser);
  }
}

犹记当时,写向数据库插入数据时,没仔细看文档,直接调用了create,结果发现数据并没有插入数据库,

  • 10
    点赞
  • 58
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值