目标
部分接口需要用户登录后才可以访问,用户登录后可以颁发 jwt_token 给前端,前端在调用需要鉴权的接口,需要在请求头添加 jwt_token,后端校验通过才能继续访问,否则返回403无权访问
创建守卫 anth
安装依赖
npm i @nestjs/jwt -S
配置 jwt 常量参数 constants/index.ts
// jwt秘钥,固定随机字符串
export const JWT_SECRET = "NODE_TEST_SECRET";
// jwt有效期 Eg: "60s", "3h", "2d"
export const JWT_EXPIRES = "2h"; // 2小时
创建 auth 模块 auth/auth.module.ts
import { Module } from '@nestjs/common';
import { JwtModule } from '@nestjs/jwt';
import { AuthService } from './auth.service';
import { JWT_SECRET, JWT_EXPIRES } from '../constants';
@Module({
imports: [
JwtModule.register({
secret: JWT_SECRET, // jwt秘钥
signOptions: {
expiresIn: JWT_EXPIRES, // jwt有效期
}
})
],
providers: [AuthService],
exports: [AuthService]
})
export class AuthModule {}
创建 auth 服务 auth/auth.service.ts
import { Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
@Injectable()
export class AuthService {
constructor(private readonly jwtService: JwtService) {}
// 创建jwt_token
async createToken(userInfo) {
// 将用户信息(userId、name)存放到 jwt 中
return {
access_token: this.jwtService.sign(userInfo)
};
}
// 校验登录状态
validateToken(token) {
try {
return this.jwtService.verify(token);
} catch {
return false;
}
}
}
创建 auth 守卫 auth/auth.guard.ts
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { AuthService } from './auth.service';
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService) {}
canActivate(context: ExecutionContext) {
const request = context.switchToHttp().getRequest();
const token = request.headers['authorization']; // 从请求头中获取 token
if (!token) {
return false;
} else {
return this.authService.validateToken(token); // 如果 token 有效,返回 true,允许访问资源
}
}
}
使用守卫 auth
需要鉴权的模块添加 auth 模块
api.module.ts
...
import { AuthModule } from '../auth/auth.module';
@Module({
imports: [AuthModule],
...
})
export class ApiModule {}
需要鉴权的接口引入守卫
api.controller.ts
...
import { Controller, Get, UseGuards } from '@nestjs/common';
import { AuthGuard } from '../auth/auth.guard';
@Controller('api')
export class ApiController {
constructor(private readonly apiService: ApiService) {}
@Get('getUserInfo')
@UseGuards(AuthGuard) // 需要鉴权的接口添加UseGuards
getUserInfo(): any {
return this.apiService.getUserInfo();
}
}
登录
调用 auth/auth.service.ts 中的 createToken 生成 jwt_token 返回给前端
前端在请求头添加 authorization
如果请求头没有 authorization,或者 authorization 失效,则返回 403 Forbidden