Skip to content

Commit

Permalink
feat: add auth refresh api
Browse files Browse the repository at this point in the history
  • Loading branch information
a20688392 committed Aug 8, 2023
1 parent c5d65d3 commit 46539da
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 6 deletions.
9 changes: 8 additions & 1 deletion src/auth/auth.controller.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Body, Controller, Post, Req, UseGuards } from "@nestjs/common";
import { Body, Controller, Get, Post, Req, UseGuards } from "@nestjs/common";
import {
ApiBadRequestResponse,
ApiBody,
Expand All @@ -18,6 +18,7 @@ import { CreateUserResponse } from "src/user/responses/create-user-response";
import { AuthService } from "./auth.service";
import { ForbiddenError } from "./exception/ForbiddenError";
import { type JwtUser } from "./jwt/jwt.interface";
import { JwtRefreshGuard } from "./jwt/jwt-refresh.guard";
import { LocalAuthGuard } from "./local/local-auth.guard";
import { GenerateTokenResponse } from "./responses/generate-token.response";

Expand Down Expand Up @@ -65,4 +66,10 @@ export class AuthController {
async login(@Req() request: Request) {
return this.authService.login(request.user as JwtUser);
}

@Get("refresh")
@UseGuards(JwtRefreshGuard)
async refresh(@Req() request: Request) {
return this.login(request);
}
}
11 changes: 8 additions & 3 deletions src/auth/auth.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import { Module } from "@nestjs/common";
import { JwtModule } from "@nestjs/jwt";
import { PassportModule } from "@nestjs/passport";
import { TypeOrmModule } from "@nestjs/typeorm";
import { jwtAccessConfig } from "src/config/jwt.config";
import { UserEntity } from "src/user/entities/user.entity";
import { UserModule } from "src/user/user.module";

import { AuthController } from "./auth.controller";
import { AuthService } from "./auth.service";
import { JwtAccessStrategy } from "./jwt/jwt-access.strategy";
import { JwtRefreshStrategy } from "./jwt/jwt-refresh.strategy";
import { LocalStrategy } from "./local/local.strategy";

@Module({
Expand All @@ -17,8 +17,13 @@ import { LocalStrategy } from "./local/local.strategy";
UserModule,
PassportModule,
TypeOrmModule.forFeature([UserEntity]),
JwtModule.registerAsync(jwtAccessConfig),
JwtModule.register({}),
],
providers: [
AuthService,
LocalStrategy,
JwtAccessStrategy,
JwtRefreshStrategy,
],
providers: [AuthService, LocalStrategy, JwtAccessStrategy],
})
export class AuthModule {}
43 changes: 41 additions & 2 deletions src/auth/auth.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ConflictException, HttpStatus, Injectable } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import { JwtService } from "@nestjs/jwt";
import { InjectRepository } from "@nestjs/typeorm";
import * as bcrypt from "bcrypt";
Expand All @@ -12,6 +13,7 @@ import { type JwtUser } from "./jwt/jwt.interface";
@Injectable()
export class AuthService {
constructor(
private readonly configService: ConfigService,
private readonly userService: UserService,
private readonly jwtService: JwtService,
@InjectRepository(UserEntity)
Expand Down Expand Up @@ -40,14 +42,23 @@ export class AuthService {
}

async login(user: JwtUser) {
const token = this.jwtService.sign(user);
const accessToken = await this.generateAccessToken(user);
const refreshToken = await this.generateRefreshToken(user);

return {
accessToken: token,
accessToken,
refreshToken,
statusCode: HttpStatus.CREATED,
};
}

async refresh(user: JwtUser) {
return {
statusCode: HttpStatus.OK,
user,
};
}

async validateUser(username: string, password: string) {
const user: UserEntity | null = await this.userService.findOne(username);

Expand All @@ -62,4 +73,32 @@ export class AuthService {

return userData;
}

async generateAccessToken(user: JwtUser): Promise<string> {
const payload: JwtUser = {
id: user.id,
};
const secret: string | undefined =
this.configService.get("jwtSecret.access");
const token = this.jwtService.sign(payload, {
expiresIn: "1h",
secret,
});

return token;
}

async generateRefreshToken(user: JwtUser): Promise<string> {
const payload: JwtUser = {
id: user.id,
};
const secret: string | undefined =
this.configService.get("jwtSecret.refresh");
const token = this.jwtService.sign(payload, {
expiresIn: "7d",
secret,
});

return token;
}
}
5 changes: 5 additions & 0 deletions src/auth/jwt/jwt-refresh.guard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Injectable } from "@nestjs/common";
import { AuthGuard } from "@nestjs/passport";

@Injectable()
export class JwtRefreshGuard extends AuthGuard("jwt-refresh") {}
28 changes: 28 additions & 0 deletions src/auth/jwt/jwt-refresh.strategy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Injectable } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import { PassportStrategy } from "@nestjs/passport";
import { ExtractJwt, Strategy } from "passport-jwt";

import { type JwtUser } from "./jwt.interface";

@Injectable()
export class JwtRefreshStrategy extends PassportStrategy(
Strategy,
"jwt-refresh",
) {
constructor(configService: ConfigService) {
const secrect: string | undefined = configService.get("jwtSecret.refresh");

super({
ignoreExpiration: false,
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: secrect,
});
}

async validate(payload: JwtUser) {
return {
payload,
};
}
}

0 comments on commit 46539da

Please sign in to comment.