feat: 使用 @nestjs-lib/auth 鉴权。
This commit is contained in:
@ -1,11 +1,11 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { PasswordConverter } from './services/password-converter';
|
||||
import { RedisMutexModule } from './redis-mutex/redis-mutex.module';
|
||||
import { JwtService } from './services/jwt.service';
|
||||
import { AuthModule } from '@nestjs-lib/auth';
|
||||
|
||||
@Module({
|
||||
providers: [PasswordConverter, JwtService],
|
||||
exports: [PasswordConverter, RedisMutexModule, JwtService],
|
||||
imports: [RedisMutexModule],
|
||||
imports: [RedisMutexModule, AuthModule],
|
||||
providers: [PasswordConverter],
|
||||
exports: [PasswordConverter, RedisMutexModule],
|
||||
})
|
||||
export class CommonsModule {}
|
||||
|
@ -1,8 +0,0 @@
|
||||
import { JwtService } from '../services/jwt.service';
|
||||
import { AccountMiddleware } from './account.middleware';
|
||||
|
||||
describe('AccountMiddleware', () => {
|
||||
it('should be defined', () => {
|
||||
expect(new AccountMiddleware({} as JwtService)).toBeDefined();
|
||||
});
|
||||
});
|
@ -1,31 +0,0 @@
|
||||
import {
|
||||
Injectable,
|
||||
NestMiddleware,
|
||||
UnauthorizedException,
|
||||
} from '@nestjs/common';
|
||||
import { JwtService } from '../services/jwt.service';
|
||||
|
||||
@Injectable()
|
||||
export class AccountMiddleware implements NestMiddleware {
|
||||
constructor(private readonly jwtService: JwtService) {}
|
||||
async use(req: any, res: any, next: () => void) {
|
||||
const authPayload = req.header('authorization') ?? '';
|
||||
if (!authPayload) {
|
||||
req.user = req.session?.user;
|
||||
next();
|
||||
return;
|
||||
}
|
||||
const token = authPayload.replace('Bearer ', '');
|
||||
if (!token) {
|
||||
throw new UnauthorizedException('授权凭据不合法!');
|
||||
}
|
||||
try {
|
||||
const { payload } = await this.jwtService.verify(token);
|
||||
req.user = payload;
|
||||
next();
|
||||
} catch (err) {
|
||||
throw new UnauthorizedException('登录凭据失效或不合法!');
|
||||
}
|
||||
next();
|
||||
}
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { generateKeyPair, KeyObject } from 'crypto';
|
||||
import { getClientToken } from 'nestjs-etcd';
|
||||
import { promisify } from 'util';
|
||||
import { JwtService } from './jwt.service';
|
||||
import { SignJWT } from 'jose/jwt/sign';
|
||||
|
||||
describe('JwtService', () => {
|
||||
let service: JwtService;
|
||||
let privateKey: KeyObject;
|
||||
let publicKey: KeyObject;
|
||||
|
||||
beforeAll(async () => {
|
||||
const pair = await promisify(generateKeyPair)('ec', {
|
||||
namedCurve: 'prime256v1',
|
||||
});
|
||||
privateKey = pair.privateKey;
|
||||
publicKey = pair.publicKey;
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [
|
||||
JwtService,
|
||||
{
|
||||
provide: getClientToken(),
|
||||
useValue: {
|
||||
get: () => ({
|
||||
buffer: () =>
|
||||
Promise.resolve(
|
||||
publicKey.export({ format: 'pem', type: 'spki' }),
|
||||
),
|
||||
}),
|
||||
},
|
||||
},
|
||||
],
|
||||
}).compile();
|
||||
|
||||
service = module.get<JwtService>(JwtService);
|
||||
await service.onModuleInit();
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
|
||||
describe('verify', () => {
|
||||
it('normal', async () => {
|
||||
const token = await new SignJWT({ userId: 'test' })
|
||||
.setProtectedHeader({ alg: 'ES256' })
|
||||
.setIssuedAt()
|
||||
.setIssuer('urn:example:issuer')
|
||||
.setAudience('urn:example:audience')
|
||||
.setExpirationTime('1h')
|
||||
.sign(privateKey);
|
||||
await expect(service.verify(token)).resolves.toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
@ -1,23 +0,0 @@
|
||||
import { OnModuleInit } from '@nestjs/common';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { KeyObject, createPublicKey } from 'crypto';
|
||||
import { jwtVerify } from 'jose/jwt/verify';
|
||||
import { Etcd3, InjectClient } from 'nestjs-etcd';
|
||||
|
||||
@Injectable()
|
||||
export class JwtService implements OnModuleInit {
|
||||
publicKey: KeyObject;
|
||||
constructor(@InjectClient() private readonly etcd: Etcd3) {}
|
||||
async onModuleInit() {
|
||||
const buff = await this.etcd
|
||||
.get('commons/auth-jwt-public-key/index')
|
||||
.buffer();
|
||||
this.publicKey = createPublicKey(buff);
|
||||
}
|
||||
|
||||
async verify(token: string) {
|
||||
return await jwtVerify(token, this.publicKey, {
|
||||
algorithms: ['PS256', 'ES256'],
|
||||
});
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user