add auth
This commit is contained in:
11
backend/src/auth/auth.module.ts
Normal file
11
backend/src/auth/auth.module.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { PassportModule } from '@nestjs/passport';
|
||||
import { JwtStrategy } from './jwt.strategy';
|
||||
import { JwtAuthGuard } from './jwt-auth.guard';
|
||||
|
||||
@Module({
|
||||
imports: [PassportModule.register({ defaultStrategy: 'jwt' })],
|
||||
providers: [JwtStrategy, JwtAuthGuard],
|
||||
exports: [JwtAuthGuard],
|
||||
})
|
||||
export class AuthModule {}
|
||||
4
backend/src/auth/decorators/public.decorator.ts
Normal file
4
backend/src/auth/decorators/public.decorator.ts
Normal file
@ -0,0 +1,4 @@
|
||||
import { SetMetadata } from '@nestjs/common';
|
||||
|
||||
export const IS_PUBLIC_KEY = 'isPublic';
|
||||
export const Public = () => SetMetadata(IS_PUBLIC_KEY, true);
|
||||
4
backend/src/auth/index.ts
Normal file
4
backend/src/auth/index.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export * from './auth.module';
|
||||
export * from './jwt-auth.guard';
|
||||
export * from './jwt.strategy';
|
||||
export * from './decorators/public.decorator';
|
||||
24
backend/src/auth/jwt-auth.guard.ts
Normal file
24
backend/src/auth/jwt-auth.guard.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import { Injectable, ExecutionContext } from '@nestjs/common';
|
||||
import { AuthGuard } from '@nestjs/passport';
|
||||
import { Reflector } from '@nestjs/core';
|
||||
import { IS_PUBLIC_KEY } from './decorators/public.decorator';
|
||||
|
||||
@Injectable()
|
||||
export class JwtAuthGuard extends AuthGuard('jwt') {
|
||||
constructor(private reflector: Reflector) {
|
||||
super();
|
||||
}
|
||||
|
||||
canActivate(context: ExecutionContext) {
|
||||
const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
|
||||
context.getHandler(),
|
||||
context.getClass(),
|
||||
]);
|
||||
|
||||
if (isPublic) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.canActivate(context);
|
||||
}
|
||||
}
|
||||
51
backend/src/auth/jwt.strategy.ts
Normal file
51
backend/src/auth/jwt.strategy.ts
Normal file
@ -0,0 +1,51 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { PassportStrategy } from '@nestjs/passport';
|
||||
import { ExtractJwt, Strategy } from 'passport-jwt';
|
||||
import { passportJwtSecret } from 'jwks-rsa';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
|
||||
export interface JwtPayload {
|
||||
sub: string;
|
||||
preferred_username: string;
|
||||
email: string;
|
||||
given_name?: string;
|
||||
family_name?: string;
|
||||
}
|
||||
|
||||
export interface AuthUser {
|
||||
userId: string;
|
||||
username: string;
|
||||
email: string;
|
||||
firstName?: string;
|
||||
lastName?: string;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class JwtStrategy extends PassportStrategy(Strategy) {
|
||||
constructor(configService: ConfigService) {
|
||||
const realmUrl = configService.get<string>('KEYCLOAK_REALM_URL');
|
||||
|
||||
super({
|
||||
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
|
||||
ignoreExpiration: false,
|
||||
issuer: realmUrl,
|
||||
algorithms: ['RS256'],
|
||||
secretOrKeyProvider: passportJwtSecret({
|
||||
cache: true,
|
||||
rateLimit: true,
|
||||
jwksRequestsPerMinute: 5,
|
||||
jwksUri: `${realmUrl}/protocol/openid-connect/certs`,
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
validate(payload: JwtPayload): AuthUser {
|
||||
return {
|
||||
userId: payload.sub,
|
||||
username: payload.preferred_username,
|
||||
email: payload.email,
|
||||
firstName: payload.given_name,
|
||||
lastName: payload.family_name,
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user