开发背景
在前面两天的文章中,介绍了一下注册功能,这里来回顾一下。
需要后端两个接口:
- 获取邮箱验证码(参数:
邮箱
、验证码类型
) - 注册(参数:
邮箱
、验证码
、密码
)
主要流程是:
- 用户点击获取验证码按钮(
自定义指令v-countdown
)调用获取验证码接口
- 后端调用封装的
Email类
发送验证码 - 用户收到验证码
- 调用
注册接口
- 后端先校验除验证码外的
其他参数
- 校验无问题调用
Redis类
读取获取到的验证码 - 开始校验验证码
- 验证码校验无问题
调用实体的save方法
将用户信息保存到用户表 - 调用
Redis类
手动删除该验证码 - 反馈给用户
注册成功
。
回顾完注册流程之后,这篇文章来聊一聊登录流程。
登录仅需要一个接口,该接口接收两个参数,邮箱
和密码
,成功之后给前端返回token
信息。本篇内容不讲接口的实现,重点放在Jwt
生成与校验token
。
开始开发
Jwt介绍
一个 JWT
实际上就是一个字符串
,它由三部分组成,头部
、载荷
与签名
。前两部分需要经过 Base64
编码,后一部分通过前两部分 Base64
编码后再加密
而成,是前后端分离之后比较通用的一种鉴权方案。
安装依赖
这里我使用的是NestJS
开发的后端服务,就来安装nestjs
对应的jwt
插件。
npm i @nestjs/jwt @nestjs/passport passport-jwt
配置文件
这里我们有一个配置文件,假设是src/config/index.ts
。
export default {
// ...
JwtConfig: {
secret: 'webxue',
signOptions: { expiresIn: '60s' },
},
}
这个配置文件导出了Jwt
的配置信息JwtConfig
,其中secret
指的是一个字符串,用来进行token
的加密,singnOptions
是个对象,expiresIn
指的是token
过期时间。
注入Jwt
需要将jwt
注入到我们的modules
中,这里我是在api.module.ts
中注入。
import { JwtModule } from '@nestjs/jwt';
import { JwtConfig } from 'src/config';
@Module({
// 在这里引入
imports: [JwtModule.register(JwtConfig)],
// ...
})
export class ApiModule {}
然后在src/common/strategy
定义Jwt策略jwt.strategy.ts
:
import { Injectable } from "@nestjs/common";
import { PassportStrategy } from "@nestjs/passport";
import { ExtractJwt, Strategy } from "passport-jwt";
import { JWT_CONFIG } from "src/config";
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor() {
super({
// 分别传入这些参数
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
secretOrKey: JWT_CONFIG.secret,
});
}
// token校验成功,会走到这里,否则会直接走401
async validate(payload: any) {
return payload;
}
}
然后将策略注入到api.module.ts
中:
import { JwtStrategy } from "src/common/strategy/jwt.strategy";
// ...
@Module({
imports: [JwtModule.register(JWT_CONFIG)],
providers: [
// ...
JwtStrategy,
],
})
生成token
在我们的登录service
内定义jwtService
:
import { JwtService } from "@nestjs/jwt";
@Injectable()
export class AuthService extends BaseService {
constructor(
// 定义jwtService
private jwtService: JwtService,
) {
super();
}
最后在登录接口内根据用户传入的email
和password
,与数据库中的数据进行对比,如果校验成功了,则通过下述代码就可以生成token
了:
const token = this.jwtService.sign(userInfo);
结语
我本是一名前端程序员,但不甘于前端,最开始学习nodejs
时使用的express
,尽管以前使用jsonwebtoken
插件做过生成
、校验
token,但通过nestjs
是第一次实现,如果哪里有什么不妥当的地方,还请大家评论指正,有讨论才有进步。最后,感谢大家能看到此处!