add refresh token
This commit is contained in:
parent
42158d1fd4
commit
96af8e564b
@ -17,12 +17,20 @@ export class App {
|
|||||||
constructor(private authService: AuthService, private router: Router) {}
|
constructor(private authService: AuthService, private router: Router) {}
|
||||||
|
|
||||||
logout(): void {
|
logout(): void {
|
||||||
// Make a best-effort to log out on the server, but always
|
// Make a best-effort to log out on the server.
|
||||||
// clean up the client-side session in the `finalize` block.
|
// The client-side logout will run regardless of whether this call
|
||||||
this.authService.serverSideLogout().pipe(
|
// succeeds or fails.
|
||||||
finalize(() => {
|
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();
|
this.authService.clientSideLogout();
|
||||||
})
|
},
|
||||||
).subscribe();
|
error: () => {
|
||||||
|
console.error("server failed to log out")
|
||||||
|
this.authService.clientSideLogout();
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -32,6 +32,7 @@ export class AuthService {
|
|||||||
* This is the definitive logout action from the user's perspective.
|
* This is the definitive logout action from the user's perspective.
|
||||||
*/
|
*/
|
||||||
clientSideLogout(): void {
|
clientSideLogout(): void {
|
||||||
|
console.info("clientSideLogout")
|
||||||
this.removeTokens();
|
this.removeTokens();
|
||||||
this.router.navigate(['/login']);
|
this.router.navigate(['/login']);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -53,10 +53,9 @@ export class JwtInterceptor implements HttpInterceptor {
|
|||||||
this.isRefreshing = false;
|
this.isRefreshing = false;
|
||||||
this.refreshTokenSubject.error(err);
|
this.refreshTokenSubject.error(err);
|
||||||
|
|
||||||
// In a refresh failure, the user MUST be logged out.
|
// The interceptor's job is done. It failed to refresh.
|
||||||
// Call the synchronous client-side logout to avoid re-intercepting.
|
// It should NOT handle logout. It should just propagate the error.
|
||||||
this.authService.clientSideLogout();
|
// The calling service/component will be responsible for the user-facing action.
|
||||||
|
|
||||||
return throwError(() => err);
|
return throwError(() => err);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|||||||
@ -6,11 +6,11 @@ import {
|
|||||||
UseGuards,
|
UseGuards,
|
||||||
Req,
|
Req,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import AuthService from './auth.service';
|
|
||||||
import { LoginRequestDto } from './dto/login-request.dto';
|
import { LoginRequestDto } from './dto/login-request.dto';
|
||||||
import { JwtAuthGuard } from './jwt-auth.guard';
|
import { JwtAuthGuard } from './jwt-auth.guard';
|
||||||
import { JwtRefreshAuthGuard } from './jwt-refresh-auth.guard';
|
import { JwtRefreshAuthGuard } from './jwt-refresh-auth.guard';
|
||||||
import express from 'express';
|
import express from 'express';
|
||||||
|
import { AuthService } from './auth.service';
|
||||||
|
|
||||||
@Controller('auth')
|
@Controller('auth')
|
||||||
export class AuthController {
|
export class AuthController {
|
||||||
|
|||||||
@ -2,23 +2,27 @@ import { Module } from '@nestjs/common';
|
|||||||
import { JwtModule } from '@nestjs/jwt';
|
import { JwtModule } from '@nestjs/jwt';
|
||||||
import { PassportModule } from '@nestjs/passport';
|
import { PassportModule } from '@nestjs/passport';
|
||||||
import { UserModule } from '../user/user.module';
|
import { UserModule } from '../user/user.module';
|
||||||
import AuthService from './auth.service';
|
import { AuthService } from './auth.service';
|
||||||
import { AuthController } from './auth.controller';
|
import { AuthController } from './auth.controller';
|
||||||
import { JwtStrategy } from './jwt.strategy';
|
import { JwtStrategy } from './jwt.strategy';
|
||||||
import { ConfigModule, ConfigService } from '@nestjs/config';
|
import { ConfigModule, ConfigService } from '@nestjs/config';
|
||||||
import { JwtRefreshTokenStrategy } from './jwt-refresh.strategy';
|
import { JwtRefreshTokenStrategy } from './jwt-refresh.strategy';
|
||||||
|
import { StringValue } from 'ms';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
ConfigModule,
|
ConfigModule,
|
||||||
UserModule,
|
UserModule,
|
||||||
PassportModule,
|
PassportModule,
|
||||||
|
// Restore the correct async registration for JwtModule
|
||||||
JwtModule.registerAsync({
|
JwtModule.registerAsync({
|
||||||
imports: [ConfigModule],
|
imports: [ConfigModule],
|
||||||
inject: [ConfigService],
|
inject: [ConfigService],
|
||||||
useFactory: (configService: ConfigService) => ({
|
useFactory: (configService: ConfigService) => ({
|
||||||
secret: configService.get<string>('JWT_SECRET'),
|
secret: configService.get<string>('JWT_SECRET'),
|
||||||
signOptions: { expiresIn: '2m' },
|
signOptions: {
|
||||||
|
expiresIn: configService.get<StringValue>('JWT_EXPIRATION_TIME'),
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import { ConfigService } from '@nestjs/config';
|
|||||||
import type { StringValue } from 'ms';
|
import type { StringValue } from 'ms';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
class AuthService {
|
export class AuthService {
|
||||||
constructor(
|
constructor(
|
||||||
private userService: UserService,
|
private userService: UserService,
|
||||||
private jwtService: JwtService,
|
private jwtService: JwtService,
|
||||||
@ -109,5 +109,3 @@ class AuthService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default AuthService;
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user