반응형
해당 글에서는 Spring Boot OAuth Client 2.0을 기반으로 ‘카카오 로그인’을 수행하기 위한 목적으로 작성한 글입니다.
💡 [참고] OAuth와 관련되어 이전에 작성한 글들입니다. : 이론 및 Security 없이 OAuth2.0 구성입니다.
1) 주요 라이브러리/프레임워크
1. Spring Boot OAuth 2 Client
💡 Spring Boot OAuth 2 Client 란?
- Spring Boot 프레임워크에서 OAuth 2.0 프로토콜을 사용하여 ‘인증’을 수행하는 클라이언트입니다.
- OAuth 2.0 프로토콜을 사용하여 인증하는 클라이언트를 구현하는 데 필요한 기능을 제공합니다. 이를 통해 서비스 제공자의 API를 사용하고 인증된 사용자 정보를 가져올 수 있습니다.
💡 [참고] Spring Boot OAuth 2 Client에 대한 정의 및 흐름, 인증방식에 대해 궁금하시면 아래의 글을 참고하시면 도움이 됩니다.
2. Spring Secuirty
💡 Spring Security 란?
- 애플리케이션 내의 보안 중 사용자에 대한 ‘인증’과 ‘인가’에 대한 처리를 담당하는 프레임워크를 의미합니다.
💡 [더 알아보기]
💡 Spring Security의 인증(Authentication)이란?
- 사용자는 자신을 입증할 수 있는 ‘정보’를 시스템에 제공하며, 시스템은 사용자에 대한 정보를 ‘검증’하여 시스템을 이용할 수 있는 사용자 인지에 대해 확인을 하는 과정을 의미합니다.
💡 Spring Security의 인가(Authorization)이란?
- 애플리케이션에서 보호된 자원(메서드 접근 혹은 요청에 대한 자원)에 대해서 접근을 허가하거나 거부하는 기능을 의미합니다.
💡 [참고] 상세한 Spring Boot Security에 대해 관심이 있으시면 아래의 글을 참고하시면 도움이 됩니다.
3. JWT(JSON Web Token)이란?
💡 JWT(JSON Web Token) 이란?
- 모바일이나 웹의 '사용자 인증’을 위해 '인증'에 필요한 정보를 토큰에 담아서 암호화를 시켜 사용하는 인터넷 표준 인증 방식을 의미합니다.
- 가볍고 자가 수용적인(self-contained) 방식으로 정보를 안전성 있게 전달해 줍니다.
[ 더 알아보기 ]
💡 자가수용적인 (self-contained) 방식
- JWT는 필요한 모든 정보를 자체적으로 지니고 있다는 장점이 있습니다.
- 이는 JWT에서 발급된 토큰은 기본 정보, 전달할 정보, 검증에 대한 모든 Signature도 포함하고 있으며, 웹 서버 환경에서는 HTTP 헤더에 포함을 시키거나 URL의 파라미터로 전달이 가능합니다.
4. Spring Boot OAuth2 Client에서 Spring Security를 적용여부에 따라 무엇이 달라지는가?
💡 Spring Boot OAuth2 Client에서 Spring Security를 적용하면 클라이언트가 보호 리소스에 액세스 할 때 access token을 사용하여 인증 수준을 검사할 수 있습니다.
💡 이를 적용하지 않는다면 access token을 이용한 검사가 이루어지지 않아, 보호 리소스에 대한 액세스 권한이 없는 클라이언트도 액세스 할 수 있습니다.
4.1. Spring Security를 적용하지 않은 경우
💡 Access Token 자체를 리소스 서버로 부터 받기에 API 접근을 할 때 검사가 이루어지지 않아 보호 리소스에 대한 액세스 권한이 없는 클라이언트도 액세스 할 수 있습니다.
4.2. Spring Security를 적용하는 경우
💡 리소스 서버로 부터 인가 코드에 대해서만 발급받고 이후는 Spring Security에서 처리를 수행합니다.
💡 프로젝트에서 사용하는 Access Token을 발급받아서 리소스 접근자에 대해서도 토큰 검사를 실시하여 리소스에 접근 시간과 제한을 둡니다.
2) 필수 환경 구성 및 라이브러리 의존성 주입
💡 해당 환경 설정에서는 인증 방식 중 ‘권한 코드 승인 방식 (Authorization Code Grant)’의 형태로 구성을 합니다.
주요한 라이브러리는 Spring Boot OAuth 2 Client와 Spring Boot Starter Security를 사용하였습니다.
1. 초기 환경 구성 : Spring Boot Security + JWT 설정
💡 해당 글에서는 Spring Boot Security + JWT에 대한 환경설정은 담고 있지 않아서 아래의 글을 참고하시면 해당 글에서와 동일한 환경설정을 구성할 수 있습니다. 그래서 사전에 이미 구성이 되었다는 가정하에 OAuth 2.0을 추가하는 형태로 작성하였습니다.
💡 [참고] 사전에 Spring Boot Security + JWT 환경설정과정을 기반으로 해당 개발환경을 구성하였습니다. (* 해당 환경이 구성되었다는 전제로 해당 개발환경 설정을 구성하였습니다)
2. 카카오 개발자(Kakao Developer) 환경 구성
💡 또한 카카오 개발자 환경이 구성이 되었다는 가정을 담고 있습니다. 아래의 글을 참고하시면 테스트를 해 볼 수 있는 설정에 대해 담고 있습니다. 참고하시면 큰 도움이 됩니다.
3. 개발 환경 라이브러리 : build.gradle
💡 해당 환경설정을 구성하는 데 사용한 라이브러리 및 프레임워크입니다.
개발 환경 | 버전 | 비고 |
java | 11 | |
Spring Boot | 2.7.5 | |
Spring Boot OAuth 2 Client | 2.7.11 | |
Spring Boot Starter Security | 2.7.5 | Spring Framework : 5.7.4 |
io.jsonwebtoken:jjwt | 0.9.1 | |
Spring Boot Starter WebFlux | 2.7.5 | |
Spring Boot Starter Data JDBC | 2.7.5 | |
mybatis | 2.2.2 | |
lombok | latest | |
postgresql | latest | |
빌드관리도구 | Gradle 7.5 | |
개발 툴 | IntelliJ IDEA 2022.3 | |
API 테스트 툴 | Postman |
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web' // Spring Boot Web
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client:2.7.11' // Spring Boot OAuth2 Client
implementation 'org.springframework.boot:spring-boot-starter-security:2.7.5' // Spring Security
implementation 'org.springframework.boot:spring-boot-starter-webflux:2.7.13' // Spring Webflux
implementation 'io.jsonwebtoken:jjwt:0.9.1' // Spring Json-Web-Token
implementation 'org.springframework.boot:spring-boot-starter-data-jdbc' // Spring Boot JDBC + HikariCP
implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.2.2' // Spring Boot MyBatis
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor' // Spring Boot yaml/yml
annotationProcessor 'org.projectlombok:lombok'
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'org.postgresql:postgresql'
}
4. OAuth 환경 파일을 구성합니다. : oauth.yml
💡 OAuth 2.0의 환경설정을 위한 파일을 별도로 분리하여서 구성합니다. (해당 소스가 길어짐에 따라 가시성이 떨어짐에 따라 별도로 관리합니다)
💡 [application.properties] 해당 파일에서는 active 속성으로 multiflex-local, multiflex-oauth 두 개를 불러오도록 구성하였습니다. 로컬의 기본설정을 관리하는 application-multiflex-local.yml 파일과 OAuth 2.0 관련 설정을 관리하는 application-multiflex-oauth.yml 파일로 분리를 하였습니다.
spring.profiles.active=multiflex-local, multiflex-oauth
server.tomcat.basedir=.
server.tomcat.accesslog.enabled=true
server.tomcat.accesslog.pattern=%{yyyy-MM-dd HH:mm:ss}t\\t%s\\t%r\\t%{User-Agent}i\\t%{Referer}i\\t%a\\t%b
💡 [참고] profiles.active 속성에 대해 궁금하시면 아래의 글을 참고하시면 됩니다.
💡 [결과] 서버가 로드될 때 두 개의 파일이 잘 불러와짐을 확인하였습니다.
5. .gitignore를 구성합니다. : .gitignore
💡 중요한 정보가 git에 올라가지 않도록 gitignore내에 키 값과 secret정보가 들어간 application-multiflex-oauth 파일을 추가합니다.
/src/main/resources/config/application-multiflex-oauth.yml
💡 [참고] Gitignore 파일을 구성하는 방법에 대해 궁금하시면 아래의 글이 도움이 됩니다.
3) 개발 초기 환경 구성
💡 해당 부분에서는 Provider의 환경 구성과 전체적인 흐름의 아키텍처에 대해 확인해 봅니다.
1. Provider 구성 : application-multiflex-oauth.yml
💡 해당 환경설정은 각각 리소스 서버(카카오, 네이버, 구글, 페이스북,…) 별로 구성하는 속성이 다르기에 공식 홈페이지의 API 문서를 확인해보셔야 합니다. ( * 해당 글에서는 Kakao를 기반으로 구성하였습니다)
[ 더 알아보기 ]
💡 Provider
- 사용자가 로그인하려는 서비스(예: Naver, Kakao, Google, Facebook, GitHub)를 의미합니다.
- Provider는 OAuth 2.0 프로토콜을 사용하여 사용자 인증 및 권한 부여를 처리합니다.
💡 application-multiflex-oauth.yml
- 해당 파일에서는 Kakao 연결을 위해 발급 정보들을 기반으로 구성하였습니다.
spring:
security:
oauth2:
client:
registration:
kakao:
client-id: 5072a6bf1008322ff506e7021db3ed63
redirect-uri:
authorization-grant-type: authorization_code
client-authentication-method: POST
client-name: Kakao
scope:
- name
- profile_nickname
- account_email
provider:
kakao:
authorization-uri: <https://kauth.kakao.com/oauth/authorize>
token-uri: <https://kauth.kakao.com/oauth/token>
user-info-uri: <https://kapi.kakao.com/v2/user/me>
user-name-attribute: id
💡 [참고] 카카오에서 로그인을 할 때 동의를 받고 가져올 수 있는 정보들입니다. : 속성 중 ‘scope’에 해당합니다.
ID | 동의 항목 명 | 기본 제공동의 단계 |
profile_nickname | 닉네임 | 필수 동의 |
profile_image | 프로필 사진 | 필수 동의 |
account_email | 카카오계정(이메일) | 선택 동의 |
name | 이름 | - |
gender | 성별 | 선택 동의 |
age_range | 연령대 | 선택 동의 |
birthday | 생일 | 선택 동의 |
birthyear | 출생 연도 | - |
phone_number | 카카오계정(전화번호) | - |
account_ci | CI(연계정보) | - |
friends | 카카오 서비스 내 친구목록(프로필사진, 닉네임, 즐겨찾기 포함) | 이용 중 동의 |
plusfriends | 카카오톡 채널 추가 상태 및 내역 | - |
shipping_address | 배송지정보(수령인명, 배송지 주소, 전화번호) | - |
story_permalink | 카카오스토리 프로필 URL | 필수 동의 |
1.1. 주요 속성에 대한 이해
💡 해당 정보는 리소스 서버로부터 발급받은 정보들을 기반으로 구성이 됩니다.
속성 | 설명 |
spring.security.oauth2.client.registration | OAuth 2.0 공급자와 클라이언트 등록 정보를 구성합니다. |
spring.security.oauth2.client.registration.{registrationId}.client-name | 등록된 클라이언트의 이름을 구성합니다. |
spring.security.oauth2.client.registration.{registrationId}.clientId | 등록된 클라이언트의 Client ID(App Key)를 구성합니다. |
spring.security.oauth2.client.registration.{registrationId}.clientSecret | 클라이언트의 Secret 구성합니다. |
spring.security.oauth2.client.registration.{registrationId}.redirectUri | 클라이언트의 리디렉션 URI를 구성합니다. |
spring.security.oauth2.client.registration.{registrationId}.authorization-grant-type | 클라이언트 인증 방법을 구성합니다. |
spring.security.oauth2.client.registration.{registrationId}.scope | 클라이언트가 요청할 수 있는 권한 범위를 구성합니다. |
spring.security.oauth2.client.provider | OAuth 2.0 공급자의 구성 정보를 구성합니다. |
spring.security.oauth2.client.provider.{providerId}.authorization-uri | OAuth 2.0 공급자의 인가 엔드포인트를 구성합니다. 인증을 위해 요청을 위한 URI |
spring.security.oauth2.client.provider.{providerId}.token-uri | OAuth 2.0 공급자의 토큰 엔드포인트를 구성합니다. 인증을 위해 |
spring.security.oauth2.client.provider.{providerId}.user-info-uri | OAuth 2.0 공급자의 사용자 정보 엔드포인트를 구성합니다. |
1.2. 이외 속성에 대한 이해
속성 | 설명 |
spring.security.oauth2.client.provider.{providerId}.authorization-uri | OAuth 2.0 공급자의 인가 엔드포인트를 구성합니다. |
spring.security.oauth2.client.provider.{providerId}.token-uri | OAuth 2.0 공급자의 토큰 엔드포인트를 구성합니다. |
spring.security.oauth2.client.provider.{providerId}.user-info-uri | OAuth 2.0 공급자의 사용자 정보 엔드포인트를 구성합니다. |
spring.security.oauth2.client.provider.{providerId}.user-name-attribute | OAuth 2.0 공급자가 사용자의 이름을 제공하는 속성을 구성합니다. |
spring.security.oauth2.client.registration.{registrationId}.client-name | 등록된 클라이언트의 이름을 구성합니다. |
spring.security.oauth2.client.registration.{registrationId}.client-authentication-method | 클라이언트의 인증 방법을 구성합니다. |
spring.security.oauth2.client.registration.{registrationId}.authorization-uri | 클라이언트 인증의 엔드포인트를 구성합니다. |
spring.security.oauth2.client.registration.{registrationId}.jwk-set-uri | 클라이언트가 사용하는 JWK 집합의 URI를 구성합니다. |
spring.security.oauth2.client.registration.{registrationId}.client-uri | 등록된 클라이언트의 URI를 구성합니다. |
spring.security.oauth2.client.registration.{registrationId}.client-configuration-uri | 등록된 클라이언트의 구성 정보를 가져오는 URI를 구성합니다. |
spring.security.oauth2.client.registration.{registrationId}.provider | OAuth 2.0 공급자의 ID를 구성합니다. |
spring.security.oauth2.client.provider.{providerId}.jwk-set-uri | OAuth 2.0 공급자가 사용하는 JWK 집합의 URI를 구성합니다. |
spring.security.oauth2.client.provider.{providerId}.user-info-authentication-method | 사용자 정보 엔드포인트에 대한 인증 방법을 구성합니다. |
spring.security.oauth2.client.provider.{providerId}.authorization-header-name | OAuth 2.0 공급자가 인가 헤더에 사용하는 이름을 구성합니다. |
spring.security.oauth2.client.provider.{providerId}.user-info-name-attribute | OAuth 2.0 공급자가 제공하는 사용자 정보에서 사용자 이름을 추출하는 속성을 구성합니다. |
spring.security.oauth2.client.provider.{providerId}.user-info-username-attribute | OAuth 2.0 공급자가 제공하는 사용자 정보에서 사용자 이름을 추출하는 데 사용되는 속성을 구성합니다. |
spring.security.oauth2.client.provider.{providerId}.clock-skew | OAuth 2.0 공급자와의 시간 차이를 구성합니다. |
spring.security.oauth2.client.registration.{registrationId}.client-id | 등록된 클라이언트의 ID를 구성합니다. |
spring.security.oauth2.client.registration.{registrationId}.client-authentication-scheme | 클라이언트의 인증 스키마를 구성합니다. |
spring.security.oauth2.client.registration.{registrationId}.client-authentication-value | 클라이언트의 인증 값을 구성합니다. |
💡 [참고] 기초 구성이 완료되었습니다.
💡 이제 실제적으로 Java 내에서 구성하는 방법에 대해 다음 글에서 공유드립니다.
오늘도 감사합니다😀
반응형
'Java > Spring Boot' 카테고리의 다른 글
[Java] Spring Web Annotation 이해하고 사용하기 -2 : 요청 및 응답 (0) | 2023.11.11 |
---|---|
[Java] Spring Web Annotation 이해하고 사용하기 -1 : 환경 구성 (2) | 2023.11.11 |
[Java] Spring Boot Web 활용 : RestTemplate 이해하기 (0) | 2023.08.14 |
[Java] Spring Boot Webflux 이해하기 -2 : 활용하기 (2) | 2023.08.13 |
[Java] Spring Boot Webflux 이해하기 -1 : 흐름 및 주요 특징 이해 (3) | 2023.08.09 |