logout works
This commit is contained in:
parent
d11b0c65e0
commit
f1f2fefdab
@ -45,7 +45,9 @@ export class JwtInterceptor implements HttpInterceptor {
|
|||||||
if (!this.isRefreshing) {
|
if (!this.isRefreshing) {
|
||||||
this.isRefreshing = true;
|
this.isRefreshing = true;
|
||||||
// Reset the refreshTokenSubject to null so that subsequent requests will wait
|
// Reset the refreshTokenSubject to null so that subsequent requests will wait
|
||||||
this.refreshTokenSubject.next(null);
|
// this.refreshTokenSubject.next(null);
|
||||||
|
this.refreshTokenSubject = new BehaviorSubject<any>(null);
|
||||||
|
|
||||||
|
|
||||||
return this.authService.refreshToken().pipe(
|
return this.authService.refreshToken().pipe(
|
||||||
switchMap((token: any) => {
|
switchMap((token: any) => {
|
||||||
|
|||||||
@ -13,3 +13,10 @@ Content-Type: application/json
|
|||||||
GET {{apiBaseUrl}}/users
|
GET {{apiBaseUrl}}/users
|
||||||
Accept: application/json
|
Accept: application/json
|
||||||
Authorization: Bearer {{auth_token}}
|
Authorization: Bearer {{auth_token}}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### GET request with parameter
|
||||||
|
POST {{apiBaseUrl}}/auth/logout
|
||||||
|
Accept: application/json
|
||||||
|
Authorization: Bearer {{auth_token}}
|
||||||
|
|||||||
@ -77,6 +77,15 @@ export class AuthService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const jwtSecret = this.configService.get<string>('JWT_SECRET');
|
||||||
|
const jwtexpirationtime = this.configService.get<string>(
|
||||||
|
'JWT_EXPIRATION_TIME',
|
||||||
|
);
|
||||||
|
|
||||||
|
console.info(
|
||||||
|
'creating. jwt secret is: ' + jwtSecret + ',' + jwtexpirationtime,
|
||||||
|
);
|
||||||
|
|
||||||
// let accessToken: string, refreshToken: string;
|
// let accessToken: string, refreshToken: string;
|
||||||
const [accessToken, refreshToken] = await Promise.all([
|
const [accessToken, refreshToken] = await Promise.all([
|
||||||
this.jwtService.signAsync(
|
this.jwtService.signAsync(
|
||||||
@ -87,7 +96,7 @@ export class AuthService {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
secret: this.configService.get<string>('JWT_SECRET'),
|
secret: this.configService.get<string>('JWT_SECRET'),
|
||||||
expiresIn: this.configService.get<StringValue>('JWT_EXPIRATION_TIME'),
|
expiresIn: +this.configService.get<StringValue>('JWT_EXPIRATION_TIME')!,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
this.jwtService.signAsync(
|
this.jwtService.signAsync(
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import { PassportStrategy } from '@nestjs/passport';
|
|||||||
import { ExtractJwt, Strategy } from 'passport-jwt';
|
import { ExtractJwt, Strategy } from 'passport-jwt';
|
||||||
import { ConfigService } from '@nestjs/config';
|
import { ConfigService } from '@nestjs/config';
|
||||||
import { Role } from './role.enum';
|
import { Role } from './role.enum';
|
||||||
|
import { Request } from 'express';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') {
|
export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') {
|
||||||
@ -10,9 +11,18 @@ export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') {
|
|||||||
super({
|
super({
|
||||||
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
|
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
|
||||||
ignoreExpiration: false,
|
ignoreExpiration: false,
|
||||||
// This is the critical fix: ensure the strategy uses the ConfigService
|
// DO NOT use secretOrKey here. It causes a race condition with ConfigService.
|
||||||
// to get the secret at runtime.
|
// Instead, use secretOrKeyProvider to look up the secret dynamically
|
||||||
secretOrKey: configService.get<string>('JWT_SECRET') as string,
|
// at request time, ensuring ConfigService is ready.
|
||||||
|
secretOrKeyProvider: (
|
||||||
|
request: Request,
|
||||||
|
rawJwtToken: any,
|
||||||
|
done: (err: any, secretOrKey?: string | Buffer) => void,
|
||||||
|
) => {
|
||||||
|
const secretKey = this.configService.get<string>('JWT_SECRET');
|
||||||
|
console.info('secretKey', secretKey);
|
||||||
|
done(null, secretKey);
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -25,6 +25,6 @@ export class User {
|
|||||||
@JoinTable()
|
@JoinTable()
|
||||||
groups: UserGroup[];
|
groups: UserGroup[];
|
||||||
|
|
||||||
@Column({ nullable: true })
|
@Column({ type: 'varchar', nullable: true })
|
||||||
hashedRefreshToken?: string;
|
hashedRefreshToken: string | null;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -67,7 +67,7 @@ export class UserService {
|
|||||||
const hashedRefreshToken = await bcrypt.hash(refreshToken, 10);
|
const hashedRefreshToken = await bcrypt.hash(refreshToken, 10);
|
||||||
await this.usersRepository.update(id, { hashedRefreshToken });
|
await this.usersRepository.update(id, { hashedRefreshToken });
|
||||||
} else {
|
} else {
|
||||||
await this.usersRepository.update(id, { hashedRefreshToken: undefined });
|
await this.usersRepository.update(id, { hashedRefreshToken: null });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user