feat: implementar melhorias na autenticação
- Adicionar refresh tokens para renovação automática de tokens - Implementar controle de sessões simultâneas - Adicionar blacklist de tokens para logout seguro - Implementar rate limiting para proteção contra ataques - Melhorar detecção de IP e identificação de sessão atual - Adicionar endpoints para gerenciamento de sessões - Corrigir inconsistências na validação de usuário - Atualizar configuração Redis com nova conexão
This commit is contained in:
@@ -7,6 +7,8 @@ import { JwtPayload } from '../models/jwt-payload.model';
|
||||
import { UserRepository } from '../../auth/users/UserRepository';
|
||||
import { RedisClientToken } from '../../core/configs/cache/redis-client.adapter.provider';
|
||||
import { IRedisClient } from '../../core/configs/cache/IRedisClient';
|
||||
import { TokenBlacklistService } from '../services/token-blacklist.service';
|
||||
import { SessionManagementService } from '../services/session-management.service';
|
||||
|
||||
@Injectable()
|
||||
export class JwtStrategy extends PassportStrategy(Strategy) {
|
||||
@@ -14,6 +16,8 @@ export class JwtStrategy extends PassportStrategy(Strategy) {
|
||||
@Inject(RedisClientToken) private readonly redis: IRedisClient,
|
||||
private readonly userRepository: UserRepository,
|
||||
private readonly configService: ConfigService,
|
||||
private readonly tokenBlacklistService: TokenBlacklistService,
|
||||
private readonly sessionManagementService: SessionManagementService,
|
||||
) {
|
||||
super({
|
||||
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
|
||||
@@ -21,13 +25,24 @@ export class JwtStrategy extends PassportStrategy(Strategy) {
|
||||
});
|
||||
}
|
||||
|
||||
async validate(payload: JwtPayload) {
|
||||
async validate(payload: JwtPayload, req: any) {
|
||||
const token = req.headers?.authorization?.replace('Bearer ', '');
|
||||
if (token && await this.tokenBlacklistService.isBlacklisted(token)) {
|
||||
throw new UnauthorizedException('Token foi invalidado');
|
||||
}
|
||||
|
||||
const sessionKey = this.buildSessionKey(payload.id);
|
||||
const cachedUser = await this.redis.get<any>(sessionKey);
|
||||
|
||||
if (cachedUser) {
|
||||
// await this.auditAccess(cachedUser);
|
||||
return cachedUser;
|
||||
return {
|
||||
id: cachedUser.id,
|
||||
sellerId: cachedUser.sellerId,
|
||||
storeId: cachedUser.storeId,
|
||||
username: cachedUser.name,
|
||||
email: cachedUser.email,
|
||||
name: cachedUser.name,
|
||||
};
|
||||
}
|
||||
|
||||
const user = await this.userRepository.findById(payload.id);
|
||||
@@ -35,13 +50,19 @@ export class JwtStrategy extends PassportStrategy(Strategy) {
|
||||
throw new UnauthorizedException('Usuário inválido ou inativo');
|
||||
}
|
||||
|
||||
await this.redis.set(sessionKey, user, 60 * 60 * 8); // 8h
|
||||
|
||||
return {
|
||||
const userData = {
|
||||
id: user.id,
|
||||
name: user.name,
|
||||
sellerId: user.sellerId,
|
||||
storeId: user.storeId,
|
||||
username: user.name,
|
||||
email: user.email,
|
||||
name: user.name,
|
||||
sessionId: payload.sessionId, // Inclui sessionId do token
|
||||
};
|
||||
|
||||
await this.redis.set(sessionKey, userData, 60 * 60 * 8);
|
||||
|
||||
return userData;
|
||||
}
|
||||
|
||||
private buildSessionKey(userId: number): string {
|
||||
|
||||
Reference in New Issue
Block a user