大厂技术 高级前端 Node进阶
点击上方 程序员成长指北,关注公众号
回复1,加入高级Node交流群
大家好我是考拉🐨,这是 Nest.js 实战系列第二篇,我要用最真实的场景让你学会使用 Node 主流框架。
先对最近催更的几个小伙伴,说一句 sorry,最近工作中 Node 后端内容做的不多,一直在做 低代码平台 相关,所以延迟了一些,不知道截图中这个小伙伴还关注我没,嘻嘻🐨,你若还在便是铁粉无疑了!
上一篇中 【Nest.js入门之基本项目搭建】 带大家入门了Nest.js
, 接下来在之前的代码上继续进行开发, 主要两个任务:实现用户的注册与登录。
在实现登录注册之前,需要先整理一下需求, 我们希望用户有两种方式可以登录进入网站来写文章, 一种是账号密码登录,另一种是微信扫码登录。文章内容大纲
接着上章内容开始...
前面我们创建文件都是一个个创建的, 其实还有一个快速创建Contoller
、Service
、Module
以及DTO
文件的方式:
nest g resouce user
这样我们就快速的创建了一个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);
}
}
在创建
User
实体, 使用@PrimaryGeneratedColumn('uuid')
创建一个主列id
,该值将使用uuid
自动生成。Uuid
是一个独特的字符串;实现字段名驼峰转下划线命名,
createTime
和updateTime
字段转为下划线命名方式存入数据库, 只需要在@Column
装饰器中指定name
属性;我们使用了装饰器
@BeforeInsert
来装饰encryptPwd
方法,表示该方法在数据插入之前调用,这样就能保证插入数据库的密码都是加密后的。给博客系统设置了三种角色
root
、autor
和visitor
,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
,结果发现数据并没有插入数据库,