데이터베이스를 어지럽히지 않고 새로 고침 토큰 자동 재사용 감지 구현
11374 단어 tutorialwebdevnodetypescript
The 🚓 Auth0 Authorization Server has been keeping track of all the refresh tokens descending from the original refresh token. That is, it has created a "token family".
Refresh Token Automatic Reuse Detection section
그러나 토큰이 손상되지 않고 애플리케이션이 많은 사용자에 의해 정기적으로 사용된다면 만료되기 전에 많은 비활성 새로 고침 토큰이 데이터베이스를 복잡하게 만들 것입니다.
솔루션
데이터베이스의 갱신 토큰 모델에 가족 속성을 추가할 수 있습니다. 이것은 Prisma ORM을 사용하는 내 모델입니다.
model UserTokens {
id String @id @default(uuid())
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
userId String
refreshToken String
family String @unique
browserInfo String? // Show the user logged devices
expiresAt DateTime
createdAt DateTime @default(now())
}
가족은 사용자가 로그인하고 새로운 새로 고침 토큰이 생성될 때 v4 UUID를 받습니다.
향후 새로 고침을 위해 tokenFamily가 새로 고침 토큰 페이로드에 추가됩니다.
다음 코드 스니펫에서 NestJS framework 및 TypeScript을 사용하고 있습니다.
/** Creates the refresh token and saves it in the database */
private async createRefreshToken(
payload: {
sub: string;
tokenFamily?: string;
},
browserInfo?: string,
): Promise<string> {
if (!payload.tokenFamily) {
payload.tokenFamily = uuidV4();
}
const refreshToken = await this.jwtService.signAsync(
{ ...payload },
refreshJwtConfig,
);
await this.saveRefreshToken({
userId: payload.sub,
refreshToken,
family: payload.tokenFamily,
browserInfo,
});
return refreshToken;
}
이제 refreshToken을 생성하고 저장했으므로 이를 사용하여 accessToken을 새로 고치고 현재 refreshToken을 회전할 수 있습니다. 그러나 먼저 유효성을 검사해야 합니다.
/** Checks if the refresh token is valid */
private async validateRefreshToken(
refreshToken: string,
refreshTokenContent: RefreshTokenPayload,
): Promise<boolean> {
const userTokens = await this.prismaService.userTokens.findMany({
where: { userId: refreshTokenContent.sub, refreshToken },
});
const isRefreshTokenValid = userTokens.length > 0;
if (!isRefreshTokenValid) {
await this.removeRefreshTokenFamilyIfCompromised(
refreshTokenContent.sub,
refreshTokenContent.tokenFamily,
);
throw new InvalidRefreshTokenException();
}
return true;
}
/** Removes a compromised refresh token family from the database
*
* If a token that is not in the database is used but it's family exists
* that means the token has been compromised and the family should me removed
*
* Refer to https://auth0.com/docs/secure/tokens/refresh-tokens/refresh-token-rotation#automatic-reuse-detection
*/
private async removeRefreshTokenFamilyIfCompromised(
userId: string,
tokenFamily: string,
): Promise<void> {
const familyTokens = await this.prismaService.userTokens.findMany({
where: { userId, family: tokenFamily },
});
if (familyTokens.length > 0) {
await this.prismaService.userTokens.deleteMany({
where: { userId, family: tokenFamily },
});
}
}
토큰이 유효하지 않지만 패밀리가 존재하는 경우 이는 원래 refreshToken에서 내려오는 토큰이므로 패밀리가 손상되었으므로 제거해야 합니다.
결론
새로 고침 토큰 회전 자동 재사용 감지를 구현하려면 원본 새로 고침 토큰을 모두 저장하지 않고 데이터베이스 모델에서 tokenFamily 속성을 만들고 등록되지 않은 자손을 확인할 수 있습니다.
이 기사에서 전체 인증 프로세스를 구현한 방법에 대해 자세히 설명하지 않았지만 원하는 경우 project's repository in GitHub에서 소스 코드를 확인할 수 있습니다.
Reference
이 문제에 관하여(데이터베이스를 어지럽히지 않고 새로 고침 토큰 자동 재사용 감지 구현), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/alvaromrveiga/implement-refresh-token-automatic-reuse-detection-without-cluttering-your-database-lb텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)