add refresh token

This commit is contained in:
Roland Schneider 2025-11-14 15:50:19 +01:00
parent 42158d1fd4
commit 96af8e564b
6 changed files with 26 additions and 16 deletions

View File

@ -17,12 +17,20 @@ export class App {
constructor(private authService: AuthService, private router: Router) {}
logout(): void {
// Make a best-effort to log out on the server, but always
// clean up the client-side session in the `finalize` block.
this.authService.serverSideLogout().pipe(
finalize(() => {
// Make a best-effort to log out on the server.
// The client-side logout will run regardless of whether this call
// succeeds or fails.
this.authService.serverSideLogout().subscribe({
// The server call can succeed or fail, we don't care about the result,
// we just want to ensure the client is logged out.
next: () => {
console.info("server logged out")
this.authService.clientSideLogout();
})
).subscribe();
},
error: () => {
console.error("server failed to log out")
this.authService.clientSideLogout();
},
});
}
}

View File

@ -32,6 +32,7 @@ export class AuthService {
* This is the definitive logout action from the user's perspective.
*/
clientSideLogout(): void {
console.info("clientSideLogout")
this.removeTokens();
this.router.navigate(['/login']);
}

View File

@ -53,10 +53,9 @@ export class JwtInterceptor implements HttpInterceptor {
this.isRefreshing = false;
this.refreshTokenSubject.error(err);
// In a refresh failure, the user MUST be logged out.
// Call the synchronous client-side logout to avoid re-intercepting.
this.authService.clientSideLogout();
// The interceptor's job is done. It failed to refresh.
// It should NOT handle logout. It should just propagate the error.
// The calling service/component will be responsible for the user-facing action.
return throwError(() => err);
})
);

View File

@ -6,11 +6,11 @@ import {
UseGuards,
Req,
} from '@nestjs/common';
import AuthService from './auth.service';
import { LoginRequestDto } from './dto/login-request.dto';
import { JwtAuthGuard } from './jwt-auth.guard';
import { JwtRefreshAuthGuard } from './jwt-refresh-auth.guard';
import express from 'express';
import { AuthService } from './auth.service';
@Controller('auth')
export class AuthController {

View File

@ -2,23 +2,27 @@ import { Module } from '@nestjs/common';
import { JwtModule } from '@nestjs/jwt';
import { PassportModule } from '@nestjs/passport';
import { UserModule } from '../user/user.module';
import AuthService from './auth.service';
import { AuthService } from './auth.service';
import { AuthController } from './auth.controller';
import { JwtStrategy } from './jwt.strategy';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { JwtRefreshTokenStrategy } from './jwt-refresh.strategy';
import { StringValue } from 'ms';
@Module({
imports: [
ConfigModule,
UserModule,
PassportModule,
// Restore the correct async registration for JwtModule
JwtModule.registerAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (configService: ConfigService) => ({
secret: configService.get<string>('JWT_SECRET'),
signOptions: { expiresIn: '2m' },
signOptions: {
expiresIn: configService.get<StringValue>('JWT_EXPIRATION_TIME'),
},
}),
}),
],

View File

@ -8,7 +8,7 @@ import { ConfigService } from '@nestjs/config';
import type { StringValue } from 'ms';
@Injectable()
class AuthService {
export class AuthService {
constructor(
private userService: UserService,
private jwtService: JwtService,
@ -109,5 +109,3 @@ class AuthService {
};
}
}
export default AuthService;