springSecurityOAuth2

์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•œ ์นด์นด์˜ค ๋„ค์ด๋ฒ„ ๋กœ๊ทธ์ธ

์Šคํ”„๋ง๋ถ€ํŠธ๊ฐ€ ์•„๋‹Œ ์Šคํ”„๋ง์—์„œ ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ์™€ OAuth2๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ SNS๋กœ๊ทธ์ธ์„ ๊ตฌํ˜„ํ•˜๋ฉด์„œ ์–ป๊ฒŒ ๋œ ์ง€์‹์„ ์ ์Šต๋‹ˆ๋‹ค. Spring Security๋กœ ๊ตฌํ˜„ํ•˜๋Š” OAuth2๋Š” ๋Œ€๋ถ€๋ถ„์˜ ํ•œ๊ธ€ ์ž๋ฃŒ๊ฐ€ ์Šคํ”„๋ง ๋ถ€ํŠธ ๊ธฐ๋ฐ˜์ด์—ˆ๊ธฐ์—, ์Šคํ”„๋ง ๊ธฐ๋ฐ˜์œผ๋กœ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด์„œ ํด๋ž˜์Šค ์ƒ์† ๊ตฌ์กฐ์™€ ์—ฌ๋Ÿฌ ๊ฐ์ฒด์˜ ๋ฉ”์†Œ๋“œ๋ฅผ ๋ณด๋Š” ๊ฒƒ์ด ์ฝ”๋“œ ์ž‘์„ฑ์— ๋งŽ์€ ๋„์›€์ด ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

OAuth 2.0์™€ ์ฃผ์š” 3๋‹จ๊ณ„ ํ”„๋กœ์„ธ์Šค

๊ณต์‹๋ฌธ์„œ : https://oauth.net/2/

OAuth 2.0๋Š” OAuth 2.0์€ ์ธ์ฆ์„ ์œ„ํ•œ ์—…๊ณ„ ํ‘œ์ค€ ํ”„๋กœํ† ์ฝœ์œผ๋กœ ์ปค์Šคํ…€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๋‹ค๋ฅธ ๋ฆฌ์†Œ์Šค ์„œ๋ฒ„(ex. ์นด์นด์˜ค, ๋„ค์ด๋ฒ„)์— ์ธ์ฆ๋œ ์‚ฌ์šฉ์ž ์ •๋ณด(ex. ์ด๋ฉ”์ผ, ์ƒ๋…„์›”์ผ ๋“ฑ์˜ ์ œํ•œ์  ์ •๋ณด)๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค. ๊ฐ€์ ธ์˜จ ์ •๋ณด๋กœ ์ธ์ฆ, ์ธ๊ฐ€ ๋“ฑ์˜ ๋กœ์ง์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์€ ์‚ฌ์šฉ์ž์˜ ๋ชซ์ด๋‹ค. ๋ณดํ†ต ์ธ๊ฐ€ ์ฝ”๋“œ ๋ฐœ๊ธ‰, ํ† ํฐ ๋ฐœ๊ธ‰, ์‚ฌ์šฉ์ž ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ์˜ 3๋‹จ๊ณ„์˜ ํ”„๋กœ์„ธ์Šค๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ๋‹ค. ์•„๋ž˜๋Š” ์„ค๋ช…์ด ๋„ˆ๋ฌด ๊น”๋”ํ•˜๊ฒŒ ๋˜์–ด ์žˆ์–ด์„œ ์นด์นด์˜ค ๋กœ๊ทธ์ธ ๊ณต์‹๋ฌธ์„œ์—์„œ ๊ฐ€์ ธ์™€ ๋ดค๋‹ค.

kakao login process

#1. ์ธ๊ฐ€ ์ฝ”๋“œ ๋ฐœ๊ธ‰ : ์‚ฌ์šฉ์ž๊ฐ€ ๋ฆฌ์†Œ์Šค ์„œ๋ฒ„์— ์ธ์ฆ๋œ ์‚ฌ์šฉ์ž์ธ์ง€ ๊ฒ€์ฆํ•˜๋Š” ๊ณผ์ •์ด๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์นด์นด์˜ค๋ฅผ ๋ฆฌ์†Œ์Šค ์„œ๋ฒ„๋กœ ์‚ฌ์šฉํ•  ๊ฒƒ์ด๋ผ๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ ์นด์นด์˜ค์— ์ธ์ฆ๋œ ์‚ฌ์šฉ์ž์ž„์„ ํ™•์ธํ•ด์•ผ ํ•œ๋‹ค. ์œ„ ๊ทธ๋ฆผ์—์„œ๋„ ๋ณผ ์ˆ˜ ์žˆ๋“ฏ์ด ์ด๋Š” ๋ณดํ†ต ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ํด๋ผ์ด์–ธํŠธ ์ธก์—์„œ ๋ฆฌ์†Œ์Šค ์„œ๋ฒ„๋กœ ์š”์ฒญ์„ ๋ณด๋‚ด๋Š” ํ˜•ํƒœ๋กœ ์ด๋ฃจ์–ด์ง„๋‹ค. ๋ฆฌ์†Œ์Šค ์„œ๋ฒ„ ์ธก์—์„œ๋Š” ํด๋ผ์ด์–ธํŠธ ์ธก์˜ ์š”์ฒญ์„ ๋ฐ›์œผ๋ฉด ๋กœ๊ทธ์ธ ํ™”๋ฉด์„ ๋‚ด๋ ค์ฃผ๊ณ , ๋™์˜ ํ•ญ๋ชฉ๊นŒ์ง€ ์‘๋‹ต๋ฐ›์œผ๋ฉด ์ด ์ •๋ณด๋ฅผ ์‚ฌ์šฉํ•  ์„œ๋ฒ„๋กœ ์ธ๊ฐ€ ์ฝ”๋“œ์™€ ํ•จ๊ป˜ redirectํ•˜๊ฒŒ ๋œ๋‹ค. spring security์—์„œ๋Š” "{baseUrl}/{action}/oauth2/code/{registrationId}"์ด default์„ค์ •์˜ redirect url์ด๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, example.com์—์„œ ์‚ฌ์šฉํ•  ๊ฒƒ์ด๊ณ , ๋กœ๊ทธ์ธ ์•ก์…˜์— ์‚ฌ์šฉํ•  ๊ฒƒ์ด๋ฉฐ, ๋ฆฌ์†Œ์†Œ ์„œ๋ฒ„๋กœ๋Š” ์นด์นด์˜ค๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ์ด๋ผ๋ฉด "https://example.com/login/oauth2/code/kakao"๊ฐ€ redirect url์ด ๋˜๊ฒ ๋‹ค. ๋‹น์—ฐํžˆ ์ด redirect url์€ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋‹ค. ๋‹ค๋งŒ ์Šคํ”„๋ง์—์„œ ๋ฐ”๊พธ์—ˆ๋‹ค๋ฉด, ๋ฆฌ์†Œ์Šค ์„œ๋ฒ„์—๋„ ๊ทธ์— ํ•ด๋‹นํ•˜๋Š” redirect url์„ค์ •์„ ํ•„์ˆ˜์ ์œผ๋กœ ํ•ด์•ผ ํ•œ๋‹ค.

#2. ํ† ํฐ ๋ฐœ๊ธ‰ : ์ธ๊ฐ€ ์ฝ”๋“œ๋ฅผ ๋ฐ›์•˜๋‹ค๋ฉด, ์ธ๊ฐ€ ์ฝ”๋“œ๋ฅผ ์š”์ฒญ์— ๋‹ด์•„ ํ† ํฐ ๋ฐœ๊ธ‰ url๋กœ ๋ณด๋‚ธ๋‹ค. ๊ทธ ํ›„ ๋ฆฌ์†Œ์Šค ์„œ๋ฒ„๋Š” ๋ฐ›์€ ์š”์ฒญ์ด ์œ ํšจํ•œ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋ณด๋ƒˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ  ํ† ํฐ์„ ๋ฐœ๊ธ‰ํ•ด์ค€๋‹ค. ์ด ํ† ํฐ์€ ์‚ฌ์šฉํ•˜๋Š” ์ž…์žฅ์—์„œ๋Š” ์ด ํ† ํฐ์ด ๋ฌด์—‡์„ ์˜๋ฏธํ•˜๋Š”์ง€ ๋ชฐ๋ผ๋„ ๋œ๋‹ค. ์‚ฌ์šฉ์ž๋Š” ๊ทธ์ € ์ด ํ† ํฐ์ด ๋งˆ์น˜ ํ˜ธํ…”ํ‚ค์ฒ˜๋Ÿผ ์œ ํšจํ•˜๊ฒŒ ๋™์ž‘ํ•  ๊ฒƒ์ด๋ผ๋Š” ์ ๋งŒ ์•Œ๋ฉด ๋œ๋‹ค. ๋ฌผ๋ก  ๋‹น์—ฐํžˆ ๋ฆฌ์†Œ์Šค ์„œ๋ฒ„์—์„œ๋Š” ์ด ํ† ํฐ์„ ํ•ด์„ํ•˜์—ฌ ์–ด๋–ค ์œ ์ €์˜ ์ •๋ณด์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ํŒ๋‹จํ•ด์•ผ ํ•œ๋‹ค. ํ˜ธํ…” ๋ฝ๋„์–ด๊ฐ€ ํ˜ธํ…”ํ‚ค๋ฅผ ํ•ด์„ํ•˜์—ฌ ๋ฐฉ๋ฒˆํ˜ธ์™€ ํ˜ธํ…”ํ‚ค๊ฐ€ ์ƒ์‘ํ•˜๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ง์ด๋‹ค.

access token๋ฅผ ํ˜ธํ…” ํ‚ค์นด๋“œ์— ๋น—๋Œ€์–ด ๊ฐ„๋‹จํžˆ ์„ค๋ช…ํ•œ ์œ ํŠœ๋ธŒ : https://www.youtube.com/watch?v=BNEoKexlmA4&ab_channel=OktaDev

#3. ์‚ฌ์šฉ์ž ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ : ํ† ํฐ์„ ๋ฐ›์•˜๋‹ค๋ฉด, ํ† ํฐ์„ Authorizationํ—ค๋”์— ๋‹ด์•„ ์‚ฌ์šฉ์ž ์ •๋ณด ์กฐํšŒ url๋กœ ์š”์ฒญํ•œ๋‹ค.

spring(without spring boot) + spring security ์กฐํ•ฉ์˜ ์นด์นด์˜ค ๋กœ๊ทธ์ธ ๊ตฌํ˜„

OAuth 2.0์€ REST API๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“  ๋ฐฑ์—”๋“œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๊ตฌํ˜„์ด ๊ฐ€๋Šฅํ•˜๋‹ค. ์ด ๋ง์ธ ์ฆ‰์Šจ ์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ์—†์–ด๋„ ๊ตฌํ˜„์ด ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ๋ง์ด๋‹ค. ์ด ๋ง์„ ํ•˜๋Š” ์ด์œ ๋Š” ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์ง€๋งŒ, ํ˜„์žฌ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ์Šคํ”„๋ง์˜ ๋ฒ„์ „์ด ๋„ˆ๋ฌด ๋‚ฎ์•„ ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ์˜ OAuth2๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด, ํ“จ์–ดํ•˜๊ฒŒ REST API๋ฅผ ์‚ฌ์šฉํ•ด์„œ OAuth2๋ฅผ ๊ตฌํ˜„ํ•œ ํ›„ ์ด๋ฅผ ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ์™€ ํ†ตํ•ฉํ•˜๋Š” ๋กœ์ง์„ ๊ตฌํ˜„ ํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. (๋ฉ”์ด๋ธ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ ๊ธฐ์ค€์œผ๋กœ ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ 5.x์ด์ƒ ๋ฒ„์ „๋ถ€ํ„ฐ oauth2 client๋ฅผ ์ง€์›ํ•œ๋‹ค.) ํ•˜์ง€๋งŒ ์Šคํ”„๋ง์—์„œ๋Š” ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ณด์•ˆ ๊ด€๋ จ ๋กœ์ง์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•˜๊ณ , ์ธ์ฆ, ์ธ๊ฐ€, ์‹œํ๋ฆฌํ‹ฐ ํ•„ํ„ฐ ๊ฐ™์€ ๊ธฐ๋Šฅ๋“ค์„ ๊ฐ„ํŽธํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋‹ˆ, ๋˜๋„๋ก์ด๋ฉด ๋ฒ„์ „์—…์„ ํ•ด์„œ ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•ด์„œ OAuth2๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ด ์˜ณ๊ฒ ๋‹ค.

#1. ๋ฆฌ์†Œ์Šค ์„œ๋ฒ„(ex. ์นด์นด์˜ค)์— ์‚ฌ์šฉ์ž(์• ํ”Œ๋ฆฌ์ผ€์ด์…˜) ๋“ฑ๋กํ•˜๊ธฐ

OAuth2.0์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์€ ์„œ๋น„์Šค์— ๋กœ๊ทธ์ธํ•ด์„œ ์–ด๋–ค ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์ด ์„œ๋น„์Šค์— ๋“ฑ๋ก๋œ ์‚ฌ์šฉ์ž์˜ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ  ์‹ถ๋‹ค๊ณ  ์•Œ๋ ค์ค˜์•ผ ํ•œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์นด์นด์˜ค๋ฅผ ๋ฆฌ์†Œ์Šค ์„œ๋ฒ„๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์‚ฌ์šฉ๋ฒ•์€ ์นด์นด์˜ค ๊ณต์‹ ๋ฌธ์„œ์— ์ž์„ธํžˆ ๋‚˜์™€ ์žˆ๋‹ค.

์นด์นด์˜ค ๋กœ๊ทธ์ธ ๊ณต์‹๋ฌธ์„œ : https://developers.kakao.com/docs/latest/ko/kakaologin/common

#2. ์‚ฌ์šฉ์ž(์• ํ”Œ๋ฆฌ์ผ€์ด์…˜)์— ๋“ฑ๋ก์ •๋ณด ์„ค์ •ํ•˜๊ธฐ

clientregistration์„ ์ง„ํ–‰ํ•˜๋Š”๋ฐ ๊ตฌ๊ธ€, ํŽ˜์ด์Šค๋ถ, ๊นƒํ—ˆ๋ธŒ๋ฅผ ๋ฆฌ์†Œ์Šค ์„œ๋ฒ„๋กœ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ CommonOAuth2Provider ์„ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ„ํŽธํ•˜๊ฒŒ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ์นด์นด์˜ค, ๋„ค์ด๋ฒ„๊ฐ™์€ ๊ฒฝ์šฐ ์ง์ ‘ OAuth2Provider๋ฅผ ๋งŒ๋“ค์–ด์ค˜์•ผ ํ•œ๋‹ค. ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ์ฐธ๊ณ ํ•ด์„œ ์„ค์ •ํ•˜์ž.

/** @Configuration **/

@Bean
public ClientRegistrationRepository clientRegistrationRepository() {
    // ๋‹ค๋ฅธ client registration์ด ํ•„์š”ํ•  ๊ฒฝ์šฐ ์•„๋ž˜ ์ƒ์„ฑ์ž์˜ ๋งค๊ฐœ๋ณ€์ˆ˜์— ์นด์นด์˜ค๋ฅผ ๋“ฑ๋กํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ์ถ”๊ฐ€ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.
    return new InMemoryClientRegistrationRepository(this.kakaoClientRegistration());
}

@Bean
public OAuth2AuthorizedClientService authorizedClientService(
        ClientRegistrationRepository clientRegistrationRepository) {
    return new InMemoryOAuth2AuthorizedClientService(clientRegistrationRepository);
}

@Bean
public OAuth2AuthorizedClientRepository authorizedClientRepository(
        OAuth2AuthorizedClientService authorizedClientService) {
    return new AuthenticatedPrincipalOAuth2AuthorizedClientRepository(authorizedClientService);
}

private ClientRegistration kakaoClientRegistration() {
    /** ๋ฆฌ์†Œ์Šค ์„œ๋ฒ„๋กœ ์นด์นด์˜ค๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.**/
    Builder builder = ClientRegistration.withRegistrationId("kakao");
    /** grant_type์œผ๋กœ๋Š” ์ธ๊ฐ€ ์ฝ”๋“œ ๋ฐ›๊ธฐ, ํ† ํฐ ๊ฐฑ์‹  ๋“ฑ์ด ์žˆ๋Š”๋ฐ ํ˜„์žฌ๋Š” ์ธ๊ฐ€ ์ฝ”๋“œ๋ฅผ ๋ฐ›์„ ๋•Œ ์‚ฌ์šฉํ•  ๊ฒƒ์ด๋ฏ€๋กœ ์•„๋ž˜์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•œ๋‹ค.**/
    builder.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE);
    /** ๋ฆฌ์†Œ์Šค ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋ฐ›์„ ์ •๋ณด ๋ฒ”์œ„์ด๊ณ , ๋ฆฌ์†Œ์Šค ์„œ๋ฒ„์— ์•ฑ์„ ๋“ฑ๋กํ•  ๋•Œ ์ ์—ˆ๋˜ ์ •๋ณด
    ๋ฒ”์œ„์™€ ์ผ์น˜ํ•ด์•ผ ํ•œ๋‹ค.**/
    builder.scope(new String[]{"profile_nickname", "account_email", "birthday"});
    /** ํด๋ผ์ด์–ธํŠธ ์ธ์ฆ ๋ฉ”์†Œ๋“œ๋Š” CLIENT_SECRET_POST๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ์ด๋‹ค. ๊ผญ ์ ์–ด์•ผ ํ•œ๋‹ค. **/
    builder.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_POST);
    /** ์•„๋ž˜ 4๊ฐœ์˜ URI๋ฅผ ์ ์œผ๋ฉด ์ž๋™์œผ๋กœ ์ธ๊ฐ€ ์ฝ”๋“œ ์š”์ฒญ, ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ url ์„ค์ •, ํ† ํฐ ์š”์ฒญ,
    ์œ ์ € ์ •๋ณด ์กฐํšŒ ์š”์ฒญ์„ ๋‹ค ๊ตฌํ˜„ํ•ด์ค€๋‹ค. **/
    builder.authorizationUri("https://kauth.kakao.com/oauth/authorize");
    builder.redirectUri("{baseUrl}/{action}/oauth2/code/{registrationId}");
    builder.tokenUri("https://kauth.kakao.com/oauth/token");
    builder.userInfoUri("https://kapi.kakao.com/v2/user/me");
    /** UserInfo Response์— ์žˆ๋Š” id๋ฅผ userNameAttributeName์œผ๋กœ ์‚ฌ์šฉํ•˜๊ฒ ๋‹ค๋Š” ์˜๋ฏธ์ด๋‹ค.
    ์‚ฌ์šฉ์ž ๊ตฌ๋ณ„ ์šฉ๋„๋กœ ์‚ฌ์šฉํ•œ๋‹ค. ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๊ฐ’์„ ์ ์œผ๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ๋ฆฌ์†Œ์Šค ์„œ๋ฒ„
    ๋ณ„๋กœ userNameAttributeName์ด ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์œผ๋‹ˆ ์ฒดํฌํ•ด์•ผ ํ•œ๋‹ค. **/
    builder.userNameAttributeName("id");
    builder.clientName("Kakao");
    builder.clientId("์•ฑ ๋“ฑ๋กํ•  ๋•Œ ๋ฐ›์€ clientId");
    builder.clientSecret("์•ฑ ๋“ฑ๋กํ•  ๋•Œ ๋ฐ›์€ clientSecret");
    return builder.build();
}

spring security without boot ๊ณต์‹ ๋ฌธ์„œ ์ฐธ๊ณ  ์ฝ”๋“œ : https://docs.spring.io/spring-security/reference/servlet/oauth2/login/core.html#oauth2login-javaconfig-wo-boot

#3. OAuth2 ๋กœ๊ทธ์ธ ๋“ฑ๋กํ•˜๊ธฐ

@RequiredArgsConstructor
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

        private final CustomOAuth2UserService customOAuth2UserService;

        @Override
        protected void configure(HttpSecurity http){
                http.oauth2Login()
                .userInfoEndpoint()
                .userService(customOAuth2UserService);
        }
}
@RequiredArgsConstructor
@Service
public class CustomOAuth2UserService implements OAuth2UserService<OAuth2UserRequest, OAuth2User> {

    private final UserService userService;

    // ๋ฆฌ์†Œ์Šค ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ์œ ์ € ์ •๋ณด๋ฅผ ๋ฐ›์•„์˜จ ํ›„ ์‹คํ–‰๋˜๋Š” ๋ฉ”์†Œ๋“œ
    @Override
    public OAuth2User loadUser(OAuth2UserRequest oAuth2UserRequest) throws OAuth2AuthenticationException {
        OAuth2UserService oAuth2UserService = new DefaultOAuth2UserService();
        OAuth2User oAuth2User = oAuth2UserService.loadUser(oAuth2UserRequest);

        /** ๊ถŒํ•œ ๋ถ€์—ฌ **/
        Set<GrantedAuthority> authorities = new LinkedHashSet();

        /** ์œ ์ € ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋กœ์ง, ํ† ํฐ ์ œ๊ณต์ž๋ณ„๋กœ ์‘๋‹ต json์˜ ๊ตฌ์กฐ๊ฐ€ ๋‹ค๋ฅด๋‹ค.**/
        Map<String, Object> kakaoAccount = (Map<String, Object>) oAuth2User.getAttributes().get("kakao_account");
        String email = (String) kakaoAccount.get("email");

        /** ์ด ๋ถ€๋ถ„์— findUserByEmail๊ฐ™์€ ๋ฉ”์„œ๋“œ๋กœ ์œ ์ €๋ฅผ ์ฐพ๊ณ  ์žˆ์œผ๋ฉด update
        ์—†์œผ๋ฉด insertํ•˜๋Š” ๋กœ์ง์„ ๋„ฃ์œผ๋ฉด ๋œ๋‹ค.**/
        
        /** ์•„๋ž˜์—์„œ ๋ฆฌํ„ดํ•˜๋Š” OAuth2User๋Š” principal์ด ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๊ธฐ์กด ์‹œํ๋ฆฌํ‹ฐ ์‚ฌ์šฉ ๋กœ์ง๊ณผ ํ†ตํ•ฉ
        ํ•˜๊ธฐ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ๋Š”๋ฐ, OAuth2User๋ฅผ ์ƒ์†ํ•˜๊ณ  CustomOAuth2User๋ฅผ ๊ตฌํ˜„ํ•˜๋ฉด ์›ํ•˜๋Š” 
        ๋กœ์ง์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.**/

        return new DefaultOAuth2User(
                authorities,
                oAuth2User.getAttributes(),
                "id");
    }
}

Last updated