前文
今天看了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
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模块导出
import { Module } from '@nestjs/common';
import { UsersService } from './users.service';
@Module({
providers: [UsersService],
exports: [UsersService],
})
export class UsersModule {}
在auth的服务里写一个基于user模块查询
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
import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';
@Module({
imports: [UsersModule],
providers: [AuthService],
})
export class AuthModule {}
然后在auth/local.strategy.ts
写一个合法性校验的函数
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模块中导入
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: [UsersModule, PassportModule],
providers: [AuthService, LocalStrategy],
})
export class AuthModule {}
使用方法,直接在对应录用中使用@UseGuards(AuthGuard('local'))
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"}
那么我们就学习了最基本的使用
可以自己动手操作一遍
目前搞不懂很正常,后续会开始逐步分析到底怎么实现的
结语
撒花~