feat: add auth using jwt

This commit is contained in:
M1000 2024-11-24 02:34:20 +01:00
parent 06b130f4e8
commit b49b7071e9
9 changed files with 318 additions and 1667 deletions

1
.env.example Normal file
View File

@ -0,0 +1 @@
JWT_SECRET=

View File

@ -14,8 +14,15 @@
}, },
"dependencies": { "dependencies": {
"@nestjs/common": "^10.0.0", "@nestjs/common": "^10.0.0",
"@nestjs/config": "^3.3.0",
"@nestjs/core": "^10.0.0", "@nestjs/core": "^10.0.0",
"@nestjs/jwt": "^10.2.0",
"@nestjs/passport": "^10.0.3",
"@nestjs/platform-express": "^10.0.0", "@nestjs/platform-express": "^10.0.0",
"axios": "^1.7.7",
"passport": "^0.7.0",
"passport-jwt": "^4.0.1",
"passport-oauth2": "^1.8.0",
"reflect-metadata": "^0.2.0", "reflect-metadata": "^0.2.0",
"rxjs": "^7.8.1" "rxjs": "^7.8.1"
}, },
@ -25,6 +32,7 @@
"@nestjs/testing": "^10.0.0", "@nestjs/testing": "^10.0.0",
"@types/express": "^5.0.0", "@types/express": "^5.0.0",
"@types/node": "^20.3.1", "@types/node": "^20.3.1",
"@types/passport-oauth2": "^1.4.17",
"@types/supertest": "^6.0.0", "@types/supertest": "^6.0.0",
"@typescript-eslint/eslint-plugin": "^8.0.0", "@typescript-eslint/eslint-plugin": "^8.0.0",
"@typescript-eslint/parser": "^8.0.0", "@typescript-eslint/parser": "^8.0.0",

View File

@ -1,12 +1,20 @@
import { Controller, Get } from "@nestjs/common"; import { Controller, Get, UseGuards } from "@nestjs/common";
import { AppService } from "./app.service"; import { AppService } from "./app.service";
import { AuthGuard } from "./auth/auth.guard";
@Controller() @Controller()
export class AppController { export class AppController {
constructor(private readonly appService: AppService) {} constructor(private readonly appService: AppService) {}
@Get() @Get()
getHello(): string { getHello() {
return this.appService.getHello();
}
@Get("protected")
@UseGuards(AuthGuard)
getProtectedHello() {
return this.appService.getHello(); return this.appService.getHello();
} }
} }

View File

@ -1,9 +1,22 @@
import { Module } from "@nestjs/common"; import { Module } from "@nestjs/common";
import { ConfigModule } from "@nestjs/config";
import { JwtModule } from "@nestjs/jwt";
import { AppController } from "./app.controller"; import { AppController } from "./app.controller";
import { AppService } from "./app.service"; import { AppService } from "./app.service";
import { AuthModule } from "./auth/auth.module";
@Module({ @Module({
imports: [], imports: [
ConfigModule.forRoot({
isGlobal: true,
}),
JwtModule.register({
global: true,
secret: process.env.JWT_SECRET,
}),
AuthModule,
],
controllers: [AppController], controllers: [AppController],
providers: [AppService], providers: [AppService],
}) })

View File

@ -2,7 +2,9 @@ import { Injectable } from "@nestjs/common";
@Injectable() @Injectable()
export class AppService { export class AppService {
getHello(): string { getHello() {
return "Hello World!"; return {
message: "Hello World!",
};
} }
} }

35
src/auth/auth.guard.ts Normal file
View File

@ -0,0 +1,35 @@
import {
CanActivate,
ExecutionContext,
Injectable,
UnauthorizedException,
} from "@nestjs/common";
import { JwtService } from "@nestjs/jwt";
import { Request } from "express";
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private jwtService: JwtService) {}
async canActivate(context: ExecutionContext): Promise<boolean> {
const request = context.switchToHttp().getRequest();
const token = this.extractTokenFromHeader(request);
if (!token) {
throw new UnauthorizedException();
}
try {
const payload = await this.jwtService.verifyAsync(token, {
secret: process.env.JWT_SECRET,
});
request["user"] = payload;
} catch {
throw new UnauthorizedException();
}
return true;
}
private extractTokenFromHeader(request: Request): string | undefined {
const [type, token] = request.headers.authorization?.split(" ") ?? [];
return type === "Bearer" ? token : undefined;
}
}

4
src/auth/auth.module.ts Normal file
View File

@ -0,0 +1,4 @@
import { Module } from '@nestjs/common';
@Module({})
export class AuthModule {}

View File

@ -3,6 +3,9 @@ import { AppModule } from "./app.module";
async function bootstrap() { async function bootstrap() {
const app = await NestFactory.create(AppModule); const app = await NestFactory.create(AppModule);
app.enableCors({
origin: "*"
});
await app.listen(process.env.PORT ?? 3000); await app.listen(process.env.PORT ?? 3000);
} }
bootstrap(); bootstrap();

1901
yarn.lock

File diff suppressed because it is too large Load Diff