📜  nestjs 授权 - Javascript (1)

📅  最后修改于: 2023-12-03 15:03:09.685000             🧑  作者: Mango

标题:NestJS 授权 - Javascript

NestJS 授权模块可用于管理用户授权和访问控制(ACL)等功能。在本文中,我们将学习如何在 NestJS 应用程序中使用授权模块。

安装与配置

首先安装授权模块:

npm i @nestjs/passport @nestjs/jwt passport-jwt

然后在应用程序模块中导入 PassportModule,同时配置 JwtModule

import { Module } from '@nestjs/common';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';

@Module({
  imports: [
    PassportModule, // 导入 PassportModule
    JwtModule.register({
      secret: process.env.JWT_SECRET,
      signOptions: { expiresIn: '60s' },
    })
  ],
})
export class AppModule {}
定义策略

接下来,我们需要定义具体的授权策略。授权策略是一个类,它实现 PassportStrategy 接口并覆盖 validate() 方法。在该方法中,我们可以通过验证用户凭证并返回用户实体来实现授权验证逻辑。

例如,我们创建一个名为 JwtStrategy 的策略类:

import { Injectable } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { AuthService } from './auth.service';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor(private readonly authService: AuthService) {
    super({
      // 从请求中提取 JWT
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      // 用于验证的 JWT secret
      secretOrKey: process.env.JWT_SECRET,
    });
  }

  async validate(payload: any) {
    // 在此处查询用户信息
    const user = await this.authService.validateUser(payload.id);
    if (!user) {
      throw new UnauthorizedException();
    }
    return user;
  }
}

JwtStrategy 中,我们使用 JwtStrategy 从请求头中获取 JWT,并使用预定义的 JWT secret 对其进行验证。然后我们查询数据库来验证用户身份。如果用户存在,则 validate() 方法返回用户对象。

创建授权服务

接下来,我们定义 AuthService 服务来处理授权逻辑。

import { Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { compare } from 'bcrypt';
import { UserService } from '../user/user.service';

@Injectable()
export class AuthService {
  constructor(
    private readonly userService: UserService,
    private readonly jwtService: JwtService,
  ) {}

  async validateUser(username: string, password: string): Promise<any> {
    const user = await this.userService.findByUsername(username);
    if (user && (await compare(password, user.password))) {
      const { password, ...result } = user;
      return result;
    }
    return null;
  }

  async login(user: any) {
    const payload = { id: user.id, username: user.username };
    return {
      access_token: this.jwtService.sign(payload),
    };
  }
}

AuthService 中,我们使用 UserService 来查询用户数据,并使用 bcrypt 模块对密码进行哈希比较。在 login() 方法中,我们使用 JwtService 来生成 JWT 并返回给客户端。

控制器和路由

现在,我们可以在控制器和路由中使用授权策略和服务。例如:

import { Controller, Request, Post, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { AuthService } from './auth.service';

@Controller()
export class AuthController {
  constructor(private readonly authService: AuthService) {}

  @UseGuards(AuthGuard('local'))
  @Post('auth/login')
  async login(@Request() req) {
    return this.authService.login(req.user);
  }

  // 受保护的路由
  @UseGuards(AuthGuard('jwt'))
  @Get('profile')
  async profile(@Request() req) {
    return req.user;
  }
}

AuthController 中,我们可以使用 AuthGuard 来保护路由。例如,在 login() 方法中,我们使用 AuthGuard('local') 来验证本地用户的身份。

profile() 方法中,我们使用 AuthGuard('jwt') 来验证 JWT 的有效性。

现在,我们已经成功在 NestJS 应用程序中应用授权模块。恭喜!

注:以上代码仅供参考,实际使用时需要根据自身的应用环境进行调整。