feat: implement global JWT auth guard with public route support
Introduced `JwtAuthGuard` as a global authentication mechanism using `APP_GUARD`. Added support for public routes via a `Public` decorator with metadata. Updated `AuthController`
This commit is contained in:
parent
4dbb858782
commit
e64d706274
@ -1,5 +1,6 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
import { ConfigModule } from '@nestjs/config';
|
import { ConfigModule } from '@nestjs/config';
|
||||||
|
import { APP_GUARD } from '@nestjs/core';
|
||||||
import { AppController } from './app.controller';
|
import { AppController } from './app.controller';
|
||||||
import { AppService } from './app.service';
|
import { AppService } from './app.service';
|
||||||
import { DatabaseModule } from './database/database.module';
|
import { DatabaseModule } from './database/database.module';
|
||||||
@ -8,6 +9,7 @@ import { ProjectsModule } from './modules/projects/projects.module';
|
|||||||
import { AuthModule } from './modules/auth/auth.module';
|
import { AuthModule } from './modules/auth/auth.module';
|
||||||
import { GroupsModule } from './modules/groups/groups.module';
|
import { GroupsModule } from './modules/groups/groups.module';
|
||||||
import { TagsModule } from './modules/tags/tags.module';
|
import { TagsModule } from './modules/tags/tags.module';
|
||||||
|
import { JwtAuthGuard } from './modules/auth/guards/jwt-auth.guard';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
@ -23,6 +25,12 @@ import { TagsModule } from './modules/tags/tags.module';
|
|||||||
TagsModule,
|
TagsModule,
|
||||||
],
|
],
|
||||||
controllers: [AppController],
|
controllers: [AppController],
|
||||||
providers: [AppService],
|
providers: [
|
||||||
|
AppService,
|
||||||
|
{
|
||||||
|
provide: APP_GUARD,
|
||||||
|
useClass: JwtAuthGuard,
|
||||||
|
},
|
||||||
|
],
|
||||||
})
|
})
|
||||||
export class AppModule {}
|
export class AppModule {}
|
||||||
|
@ -16,6 +16,7 @@ import { GithubAuthGuard } from '../guards/github-auth.guard';
|
|||||||
import { JwtAuthGuard } from '../guards/jwt-auth.guard';
|
import { JwtAuthGuard } from '../guards/jwt-auth.guard';
|
||||||
import { JwtRefreshGuard } from '../guards/jwt-refresh.guard';
|
import { JwtRefreshGuard } from '../guards/jwt-refresh.guard';
|
||||||
import { GetUser } from '../decorators/get-user.decorator';
|
import { GetUser } from '../decorators/get-user.decorator';
|
||||||
|
import { Public } from '../decorators/public.decorator';
|
||||||
|
|
||||||
@Controller('auth')
|
@Controller('auth')
|
||||||
export class AuthController {
|
export class AuthController {
|
||||||
@ -27,6 +28,7 @@ export class AuthController {
|
|||||||
/**
|
/**
|
||||||
* Initiate GitHub OAuth flow
|
* Initiate GitHub OAuth flow
|
||||||
*/
|
*/
|
||||||
|
@Public()
|
||||||
@Get('github')
|
@Get('github')
|
||||||
@UseGuards(GithubAuthGuard)
|
@UseGuards(GithubAuthGuard)
|
||||||
githubAuth() {
|
githubAuth() {
|
||||||
@ -37,6 +39,7 @@ export class AuthController {
|
|||||||
/**
|
/**
|
||||||
* Handle GitHub OAuth callback
|
* Handle GitHub OAuth callback
|
||||||
*/
|
*/
|
||||||
|
@Public()
|
||||||
@Get('github/callback')
|
@Get('github/callback')
|
||||||
@UseGuards(GithubAuthGuard)
|
@UseGuards(GithubAuthGuard)
|
||||||
async githubAuthCallback(@Req() req: Request, @Res() res: Response) {
|
async githubAuthCallback(@Req() req: Request, @Res() res: Response) {
|
||||||
@ -61,6 +64,7 @@ export class AuthController {
|
|||||||
/**
|
/**
|
||||||
* Refresh tokens
|
* Refresh tokens
|
||||||
*/
|
*/
|
||||||
|
@Public()
|
||||||
@Post('refresh')
|
@Post('refresh')
|
||||||
@UseGuards(JwtRefreshGuard)
|
@UseGuards(JwtRefreshGuard)
|
||||||
async refreshTokens(@GetUser() user) {
|
async refreshTokens(@GetUser() user) {
|
||||||
|
14
backend/src/modules/auth/decorators/public.decorator.ts
Normal file
14
backend/src/modules/auth/decorators/public.decorator.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { SetMetadata } from '@nestjs/common';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Key for the public metadata
|
||||||
|
*/
|
||||||
|
export const IS_PUBLIC_KEY = 'isPublic';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decorator to mark a route as public (not requiring authentication)
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
* - @Public() - Mark a route as public
|
||||||
|
*/
|
||||||
|
export const Public = () => SetMetadata(IS_PUBLIC_KEY, true);
|
@ -1,11 +1,33 @@
|
|||||||
import { Injectable, UnauthorizedException } from '@nestjs/common';
|
import { Injectable, UnauthorizedException, ExecutionContext } from '@nestjs/common';
|
||||||
import { AuthGuard } from '@nestjs/passport';
|
import { AuthGuard } from '@nestjs/passport';
|
||||||
|
import { Reflector } from '@nestjs/core';
|
||||||
|
import { IS_PUBLIC_KEY } from '../decorators/public.decorator';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Guard for JWT authentication
|
* Guard for JWT authentication
|
||||||
*/
|
*/
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class JwtAuthGuard extends AuthGuard('jwt') {
|
export class JwtAuthGuard extends AuthGuard('jwt') {
|
||||||
|
constructor(private reflector: Reflector) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the route is public or requires authentication
|
||||||
|
*/
|
||||||
|
canActivate(context: ExecutionContext) {
|
||||||
|
const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
|
||||||
|
context.getHandler(),
|
||||||
|
context.getClass(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (isPublic) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.canActivate(context);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle unauthorized errors
|
* Handle unauthorized errors
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user