李恒道 发表于 2022-12-4 00:12:16

nestjs passport及@nestjs/passport源码级分析(一)

# 前文
今天看了nestjs的passport鉴权教程
当时真的感觉...
一言难尽,只教你创建目录,贴文件,但是不教到底为什么
然后我决定看看官方的教程
https://docs.nestjs.com/security/authentication
发现...
他妈的一个吊样啊喂
那个人就是抄的官网啊喂
所以到底有没有人讲讲
经过很久的查阅资料...
发现,没人研究过= =
于是clone了一份源码自己慢慢读吧...
所以就有了这篇文章!
我们先大概理一下官方教程都做了什么
https://docs.nestjs.com/security/authentication
# 使用的库
我们使用了nestjs框架,库尤passport,passport-local以及对应的类型库
你可以输入下列命令安装
npm install --save @nestjs/passport passport passport-local
npm install --save-dev @types/passport-local
# 官方教程中passport使用
$ nest g module auth
$ nest g service auth
生成了一个auth模块和服务
$ nest g module users
$ nest g service users
生成了一个user模块和服务
user服务写了一个简单的查询demo
```javascript
import { Injectable } from '@nestjs/common';

// This should be a real class/interface representing a user entity
export type User = any;

@Injectable()
export class UsersService {
private readonly users = [
    {
      userId: 1,
      username: 'john',
      password: 'changeme',
    },
    {
      userId: 2,
      username: 'maria',
      password: 'guess',
    },
];

async findOne(username: string): Promise<User | undefined> {
    return this.users.find(user => user.username === username);
}
}
```
然后在user模块导出
```javascript
import { Module } from '@nestjs/common';
import { UsersService } from './users.service';

@Module({
providers: ,
exports: ,
})
export class UsersModule {}
```
在auth的服务里写一个基于user模块查询
```javascript
import { Injectable } from '@nestjs/common';
import { UsersService } from '../users/users.service';

@Injectable()
export class AuthService {
constructor(private usersService: UsersService) {}

async validateUser(username: string, pass: string): Promise<any> {
    const user = await this.usersService.findOne(username);
    if (user && user.password === pass) {
      const { password, ...result } = user;
      return result;
    }
    return null;
}
}
```
并且在auth模块导入user
```js
import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';

@Module({
imports: ,
providers: ,
})
export class AuthModule {}
```
然后在auth/local.strategy.ts
写一个合法性校验的函数
```js
import { Strategy } from 'passport-local';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { AuthService } from './auth.service';

@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
constructor(private authService: AuthService) {
    super();
}

async validate(username: string, password: string): Promise<any> {
    const user = await this.authService.validateUser(username, password);
    if (!user) {
      throw new UnauthorizedException();
    }
    return user;
}
}
```
并且在auth模块中导入
```js
import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';
import { LocalStrategy } from './local.strategy';

@Module({
imports: ,
providers: ,
})
export class AuthModule {}

```
使用方法,直接在对应录用中使用@UseGuards(AuthGuard('local'))
```js
import { Controller, Request, Post, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Controller()
export class AppController {
@UseGuards(AuthGuard('local'))
@Post('auth/login')
async login(@Request() req) {
    return req.user;
}
}
```
# 测试
使用curl,当然你也可以使用postman
```
$ # POST to /auth/login
$ curl -X POST http://localhost:3000/auth/login -d '{"username": "john", "password": "changeme"}' -H "Content-Type: application/json"
$ # result -> {"userId":1,"username":"john"}
```
那么我们就学习了最基本的使用
可以自己动手操作一遍
目前搞不懂很正常,后续会开始逐步分析到底怎么实现的
# 结语
撒花~
页: [1]
查看完整版本: nestjs passport及@nestjs/passport源码级分析(一)