让我来给您详细讲解关于 "Nest.js 授权验证的方法示例" 的完整攻略。
标准安装
首先,需要使用 npm 安装 nestjs 官方授权验证库:
npm i @nestjs/passport @nestjs/jwt passport-jwt
安装了该插件后,我们还需要为它配置启用策略和秘钥等信息。例如:
// auth.module.ts
import { Module } from '@nestjs/common';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
import { JwtStrategy } from './jwt.strategy';
import { AuthService } from './auth.service';
import { AuthController } from './auth.controller';
@Module({
imports: [
PassportModule.register({ defaultStrategy: 'jwt' }),
JwtModule.register({
secret: 'SECRET_KEY',
signOptions: { expiresIn: '86400s' },
}),
],
providers: [AuthService, JwtStrategy],
controllers: [AuthController],
exports: [PassportModule, JwtModule],
})
export class AuthModule {}
在 JwtModule.register()
中设置了秘钥以及过期时间。在 PassportModule.register()
指定了默认的策略为 jwt
,并且在后续请求中将会自动执行策略。
然后,我们需要创建 JwtStrategy
文件并且声明为 PassportModule
的提供者供 AuthGuard
直接调用:
// jwt.strategy.ts
import { Injectable } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { JwtPayload } from './jwt-payload.interface';
@Module({
providers: [JwtStrategy],
})
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor() {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: 'SECRET_KEY',
});
}
async validate(payload: JwtPayload) {
return { userId: payload.sub, username: payload.username };
}
}
在 JwtStrategy
中,我们使用 passport-jwt
包来验证 JWT 令牌,并且提供了一个 validate()
方法来验证 JWT 的有效性。该方法会自动将JWT的payload属性返回,以便下一步处理该信息。
当Token 通过 jwt
策略被验证,系统会自动调用 validate()
方法,返回一个对象,其中包含用户的信息。
示例1:授权Token并验证用户信息
接下来,我们简单介绍一下如何在系统中授权Token并且验证用户信息。
首先,在 auth.service.ts
文件中,我们需要创建一个用于授权用户的方法 signIn()
:
// auth.service.ts
import { Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { UserService } from '../user/user.service';
import { User } from '../user/user.entity';
@Injectable()
export class AuthService {
constructor(
private readonly userService: UserService,
private readonly jwtService: JwtService,
) {}
async signIn(user: User) {
const payload = { username: user.username, sub: user.userId };
return {
access_token: this.jwtService.sign(payload),
};
}
async validateUser(username: string, password: string): Promise<any> {
const user = await this.userService.findOne(username);
if (user && user.password === password) {
const { password, ...result } = user;
return result;
}
return null;
}
}
该方法会创建一个 JWT token 并且返回给用户。并且注意,我们需要在头部注入 Authorization:Bearer "access_token"
来启用授权策略并且默认为JWT策略。
接下来,创建一个 protected
的路由:
// cats.controller.ts
import { Controller, Get, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { CatsService } from './cats.service';
import { Cat } from './cat.entity';
@Controller('cats')
export class CatsController {
constructor(private readonly catsService: CatsService) {}
@UseGuards(AuthGuard('jwt'))
@Get()
async findAll(): Promise<Cat[]> {
return this.catsService.findAll();
}
}
在代码中,@UseGuards(AuthGuard('jwt'))
会验证请求头是否包含 JWT token,如果是则自动将 payload
属性返回给 JwtStrategy
。在这种情况下,我们在请求中访问的每个路由都会首先执行 'jwt' 策略来验证其有效性。
示例2: 权限守卫
以上示例主要用于授权并且自动验证用户信息。下面,我们会介绍一下如何使用 Permissions 守卫来进行更复杂的 “角色身份验证” 实现身份验证。
// roles.guard.ts
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
@Injectable()
export class RolesGuard implements CanActivate {
constructor(private readonly reflector: Reflector) {}
canActivate(context: ExecutionContext): boolean {
const roles = this.reflector.get<string[]>('roles', context.getHandler());
if (!roles) {
return true;
}
const request = context.switchToHttp().getRequest();
const user = request.user;
const hasRole = () =>
user.roles.some(role => roles.indexOf(role) !== -1);
return user && user.roles && hasRole();
}
}
在上面的代码中,我们首先从请求中获取 roles
参数,并检查 user.roles
中是否有相应的角色。如果存在且匹配成功,则返回 true
。
// cats.controller.ts
import { Controller, Get, UseGuards, SetMetadata } from '@nestjs/common';
import { RolesGuard } from '../roles/roles.guard';
import { Cat } from './cat.entity';
import { CatsService } from './cats.service';
import { Roles } from '../roles/roles.decorator';
@Controller('cats')
export class CatsController {
constructor(private readonly catsService: CatsService) {}
@UseGuards(RolesGuard)
@Roles('admin')
@Get()
async findAll(): Promise<Cat[]> {
return this.catsService.findAll();
}
}
在执行例子 2 时,我们在路由中使用了 @Roles('admin)
守卫。在守卫中,我们将user对象与角色名称进行比较。如果请求不包含admin权限,则返回403 Forbidden错误。
以上就是关于 Nest.js 授权验证的方法示例攻略的详细讲解,希望对您有所帮助。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Nest.js 授权验证的方法示例 - Python技术站