OAuth란?
OAuth(Open Authorization)는 인터넷 사용자들이 비밀번호를 제공하지 않고도 애플리케이션이나 웹사이트가 사용자 정보를 접근할 수 있도록 허가하는 표준 인증 프로토콜입니다. 간단히 말해, OAuth를 통해 사용자는 자신의 계정 정보를 안전하게 공유할 수 있습니다.
주요 개념:
- 인가 코드(Authorization Code): 사용자가 애플리케이션에 접근 권한을 부여할 때 발급받는 코드입니다.
- 액세스 토큰(Access Token): 애플리케이션이 사용자 데이터를 접근하기 위해 사용하는 토큰입니다.
- 리다이렉션 URI(Redirection URI): 인가 코드 또는 액세스 토큰을 받을 URI입니다.
사용 사례:
- 소셜 로그인: 사용자가 Facebook, Google, Kakao 등의 계정을 사용하여 다른 애플리케이션에 로그인할 때 사용됩니다.
- API 접근: 외부 애플리케이션이 사용자 데이터를 접근할 때 OAuth를 통해 안전하게 접근할 수 있습니다.
RSA란?
RSA(Rivest-Shamir-Adleman)는 널리 사용되는 공개 키 암호화 알고리즘 중 하나입니다. RSA는 두 개의 키(공개 키와 비밀 키)를 사용하여 데이터를 암호화하고 복호화합니다. 공개 키는 누구나 접근할 수 있도록 공개되며, 비밀 키는 데이터 소유자만이 접근할 수 있도록 보호됩니다.
주요 개념:
- 공개 키(Public Key): 데이터를 암호화하는 데 사용되며, 누구나 접근할 수 있습니다.
- 비밀 키(Private Key): 데이터를 복호화하는 데 사용되며, 데이터 소유자만이 접근할 수 있습니다.
- 암호화(Encryption): 평문 데이터를 공개 키를 사용하여 암호문으로 변환하는 과정입니다.
- 복호화(Decryption): 암호문 데이터를 비밀 키를 사용하여 평문 데이터로 변환하는 과정입니다.
직접 해보기
카카오 사이트를 참조하여 진행합니다.
- 애플리케이션 등록
- 애플리케이션 설정
- 플랫폼 등록 : 사용할 플랫폼을 등록합니다.
- 로그인 활성화 : 애플리케이션에서 로그인을 활성화합니다.
- 오픈 Id 활성화 : 오픈 ID를 활성화합니다.
- 리다이렉션 주소 설정 : 리다이렉션 주소를 설정합니다.
- 동의항목 체크 : 필요한 동의항목 (예 ;닉네임) 을 체크합니다.
- 연동 개발 (RestAPI)
- 인가 코드 받기 (아래의 주소를 사용하여 인가 코드를 요청합니다.)
- 토큰 받기
예시 주소 :
https://kauth.kakao.com/oauth/authorize?client_id=caefd05138bce05df366ee94d807a224&redirect_uri=http://localhost:8080/oauth&response_type=code
위 주소로 get 요청시 아래 이미지처럼 인가 코드를 받을 수 있습니다. (일회용)

다음과 같은 POST 요청을 통해 토큰을 받습니다:
위의 과정을 PostMan으로 실행한 결과 이미지 :

참고 사항
grant_type의 value는 항상 authorization_code 입니다.
다른 값들을 찾으려면 아래의 이미지를 참고하세요



JWT 토큰 검증 예제
다음은 JWT 토큰을 검증하는 예제 테스트 코드입니다
라이브러리 추가 :
implementation 'com.nimbusds:nimbus-jose-jwt:9.31'
테스트 코드 :
package com.metacoding.oidcsample.util;
import com.nimbusds.jose.JWSObject;
import com.nimbusds.jose.crypto.RSASSAVerifier;
import com.nimbusds.jose.jwk.RSAKey;
import com.nimbusds.jose.util.Base64URL;
import com.nimbusds.jwt.SignedJWT;
import org.junit.jupiter.api.Test;
import java.text.ParseException;
import java.util.Base64;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class IdTokenTest {
@Test
public void tokenVerify_test() {
String idToken = "eyJraWQiOiI5ZjI1MmRhZGQ1ZjIzM2Y5M2QyZmE1MjhkMTJmZWEiLCJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiJjYWVmZDA1MTM4YmNlMDVkZjM2NmVlOTRkODA3YTIyNCIsInN1YiI6IjM4Mjc3NDU0NzQiLCJhdXRoX3RpbWUiOjE3MzM3OTIzOTMsImlzcyI6Imh0dHBzOi8va2F1dGgua2FrYW8uY29tIiwibmlja25hbWUiOiLrsJXrrLTtmIQiLCJleHAiOjE3MzM4MTM5OTMsImlhdCI6MTczMzc5MjM5M30.UFUnYArjWFjJMiqlWxdWXrIkR5K68dpVSxkVPZjwHPkPPfzvjt-Wo-sYYTDCPWYOrbn96NW_BSNWR5SS4WGGGvuAn9EsQMkqZh2hruzo9UggwDSwJLOMtlBLLjoXMW8JQWEAQDEkjep64i4ft0MXK52U5TT3GCQzSce5U6Y_8l3X4gBchUUqAX3-qvFXqElij-ZWy1sJ5yD6wE353rCt4b0FDDpGXmCc1_vpMtqcj9IE77zr1rsQt1Al11pKqNQGnT_Jq2YwDMvxHCjfeZW4W1kHIfvZ1lfCHQCBW5qkaYkwWT7q19D8Bv3jbQ6nD-sR5dIx-thxMranLVWhPCmTFA";
String n = "qGWf6RVzV2pM8YqJ6by5exoixIlTvdXDfYj2v7E6xkoYmesAjp_1IYL7rzhpUYqIkWX0P4wOwAsg-Ud8PcMHggfwUNPOcqgSk1hAIHr63zSlG8xatQb17q9LrWny2HWkUVEU30PxxHsLcuzmfhbRx8kOrNfJEirIuqSyWF_OBHeEgBgYjydd_c8vPo7IiH-pijZn4ZouPsEg7wtdIX3-0ZcXXDbFkaDaqClfqmVCLNBhg3DKYDQOoyWXrpFKUXUFuk2FTCqWaQJ0GniO4p_ppkYIf4zhlwUYfXZEhm8cBo6H2EgukntDbTgnoha8kNunTPekxWTDhE5wGAt6YpT4Yw";
String e = "AQAB";
Base64URL modulus = Base64URL.from(n);
Base64URL exponent = Base64URL.from(e);
// RSA 공개 키 생성
RSAKey rsaKey = new RSAKey.Builder(modulus, exponent).build();
try {
// JWT 토큰 파싱
SignedJWT signedJWT = SignedJWT.parse(idToken);
// JWT 서명 검증
RSASSAVerifier verifier = new RSASSAVerifier(rsaKey);
boolean isValid = signedJWT.verify(verifier);
if (isValid) {
System.out.println("서명 정상");
} else {
System.out.println("서명 비정상");
}
} catch (Exception e) {
System.out.println("오류 발생");
e.printStackTrace();
}
}
}
- idToken : 전달 받은 토큰 값 입니다.
- n, e : 공개키의 값 입니다.

위 주소를 get 요청 했을 때 :

kid값을 찾는 방법 :
https://jwt.io/ 사이트에서 전달받은 id_token 값을 집어넣으면 header 쪽에 kid 값이 있습니다.
해당 값을 비교하여 자신에게 맞는 공개키를 찾을 수 있습니다.
Share article