Contents
ID 토큰 유효성 검증하기OAuth로 토큰을 받고 OIDC로 인증과 인가를 하는 이유
- OIDC는 OAuth 2.0의 확장으로, 사용자 인증과 관련된 기능을 추가합니다.
- OAuth 2.0의 권한 부여와 OIDC의 인증을 통합하여 사용할 수 있습니다.
- JWT를 활용한 토큰 기반 인증(Token-Based Authentication)이 가능합니다.
- 다양한 클라이언트 유형(웹, 모바일, 데스크탑)과 호환이 가능합니다.
- ID 토큰에 사용자 정보가 있기 때문에 요청을 2번 하지 않아도 됩니다.
ID 토큰 유효성 검증하기
1) ID 토큰
- ID 토큰은 서비스의 로그인 세션 대신 사용할 수 있는 JSON Web Token(JWT) 형식의 토큰입니다.
- 서비스는 ID 토큰에 포함된 사용자 인증 정보를 서비스에 활용하거나, ID 토큰의 유효성을 검증할 수 있습니다.
- ID 토큰의 만료 시간은 액세스 토큰과 동일합니다.
2) OIDC: 공개키 목록 조회하기

- 주의사항
- 지나치게 빈번한 공개키 목록 조회 요청 시, 요청이 차단될 수 있습니다.
- 공개키가 2개 있는데 kid가 일치하는 공개키를 사용하면 됩니다.
- 공개키 타입은 RSA입니다.
3) ID 토큰의 kid 확인
- 위 사이트에서 ID 토큰을 넣으면 확인할 수 있습니다.

4) Spring에서 ID 토큰 유효성 검증
- 라이브러리 세팅
- gradle
implementation 'com.nimbusds:nimbus-jose-jwt:9.31'
- IdTokenTest
public class IdTokenTest {
@Test
public void tokenVerify_test() {
String idToken = "eyJraWQiOiI5ZjI1MmRhZGQ1ZjIzM2Y5M2QyZmE1MjhkMTJmZWEiLCJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiI3MzBhOGVjN2U5MWYwNGFiMjY0Nzk5MWVmMzRmMWY4MSIsInN1YiI6IjM4Mjc3MzEwNTgiLCJhdXRoX3RpbWUiOjE3MzM3OTE2ODEsImlzcyI6Imh0dHBzOi8va2F1dGgua2FrYW8uY29tIiwibmlja25hbWUiOiLstZzso7ztmLgiLCJleHAiOjE3MzM4MTMyODEsImlhdCI6MTczMzc5MTY4MX0.mMT4oqaT8TCnWMaKMVthpS5JdLj0itI0wn8rZm1AketyGxOYYU2fDtcVHcUvprGFgTZ3y9QCKZd6xUMtWF7eM7LgYqAhY9uY8hR_ms11tNGbWf-67j9NSJ9TpwEbTHxtLF3xjIAQOpaACRmwpqvUXn5GF_ct2ko_35LOtOOHxjGKMHs219Obb85sbEO-Rwlqi3qXEc79myfYOB1FdaOrxyG_NJtxeKHJPwzcfWo2HGdkZaf31k0XpZSYQug1yiM1L3NzVpe7_rWhg_ku_k0mp7IyS7AoLDOyceUl6kmck4XP7gVEZtKdaViVZqKA_Y6xbO7aMfNYDdnG_FaanhzBLg";
String n = "qGWf6RVzV2pM8YqJ6by5exoixIlTvdXDfYj2v7E6xkoYmesAjp_1IYL7rzhpUYqIkWX0P4wOwAsg-Ud8PcMHggfwUNPOcqgSk1hAIHr63zSlG8xatQb17q9LrWny2HWkUVEU30PxxHsLcuzmfhbRx8kOrNfJEirIuqSyWF_OBHeEgBgYjydd_c8vPo7IiH-pijZn4ZouPsEg7wtdIX3-0ZcXXDbFkaDaqClfqmVCLNBhg3DKYDQOoyWXrpFKUXUFuk2FTCqWaQJ0GniO4p_ppkYIf4zhlwUYfXZEhm8cBo6H2EgukntDbTgnoha8kNunTPekxWTDhE5wGAt6YpT4Yw";
String e = "AQAB";
BigInteger bin = new BigInteger(1, Base64.getUrlDecoder().decode(n));
BigInteger bie = new BigInteger(1, Base64.getUrlDecoder().decode(e));
RSAKey rsaKey = new RSAKey.Builder(Base64URL.encode(bin), Base64URL.encode(bie)).build();
try {
// 1. 파싱
SignedJWT signedJWT = SignedJWT.parse(idToken);
// 2. 검증
RSASSAVerifier verifier = new RSASSAVerifier(rsaKey.toRSAPublicKey());
if (signedJWT.verify(verifier)) {
System.out.println("ID Token을 검증하였습니다");
System.out.println("Payload : " + signedJWT.getPayload());
} else {
System.out.println("검증에 실패하였습니다.");
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
- 인증 완료 시 결과
ID Token을 검증하였습니다
Payload : {
"aud":"730a8ec7e91f04ab2647991ef34f1f81",
"sub":"3827731058",
"auth_time":1733791681,
"iss":"https://kauth.kakao.com",
"nickname":"닉네임",
"exp":1733813281,
"iat":1733791681
}
아래로 이어집니다
Share article