Search
🔑

소셜 로그인 리다이렉트

태그
OAuth2.0
목차

프로젝트의 OAuth2.0 구조

저희 프로젝트의 경우 소셜 로그인을 Rest api 방식이 아닌 Spring boot 에서 OAuth2.0 프로토콜을 이용하여 구현하였습니다. 때문에 로그인 할 수 있는 특정 url 이 삽입된 버튼을 클릭하면 특정 소셜 로그인 화면이 나오고, 소셜 로그인에 성공하면 해당 유저의 정보로 회원가입 / 로그인을 동시에 한 뒤 유저 정보를 반환하게 됩니다.

이렇게 하면 뭐가 문제인가요?

이런식으로 리다이렉트 됩니다. 프론트에서 아래와 같이 잡아도
<script setup> import { ref, onMounted } from 'vue'; import axios from 'axios'; import router from "../../router/index.js"; const responseData = ref(null); onMounted(async () => { try { const response = await axios.post('https://dev.travel-planner.xyz/oauth/callback'); responseData.value = response.data; console.log('Response Data:', responseData.value); if (response.status === 200) { await router.push('/feed'); } } catch (error) { console.error('Error:', error); } }); </script>
JavaScript
복사
리다이렉트 되는 주소가 서버 주소이기 때문에 위와 같은 화면이 나올 수 밖에 없었습니다.

프론트 주소로 리다이렉트 하기

이를 해결하기 위해 아래와 같이 소셜로그인에 성공하면 유저 정보를 리퀘스트 파라미터로 유저 정보를 넣은 주소를 반환 하는 방식으로 변경하였습니다.
String encodedUserId = URLEncoder.encode(String.valueOf(authResponse.getUserId()), StandardCharsets.UTF_8); String encodedEmail = URLEncoder.encode(authResponse.getEmail(), StandardCharsets.UTF_8); String encodedNickname = URLEncoder.encode(authResponse.getUserNickname(), StandardCharsets.UTF_8); String encodedProvider = URLEncoder.encode(authResponse.getProvider(), StandardCharsets.UTF_8); String encodedProfileImgUrl = URLEncoder.encode(authResponse.getProfileImgUrl(), StandardCharsets.UTF_8); // 프론트엔드 페이지로 토큰과 함께 리다이렉트 String frontendRedirectUrl = String.format( "%s/oauth/callback?token=%s&userId=%s&email=%s&nickname=%s&provider=%s&profileImgUrl=%s", frontendRedirectUri, accessToken, encodedUserId, encodedEmail, encodedNickname, encodedProvider, encodedProfileImgUrl ); response.sendRedirect(frontendRedirectUrl);
Java
복사
프론트의 경우 아래와 같이 변경하였습니다.
<template> </template> <script setup> import { ref, onMounted } from 'vue'; import { useRoute, useRouter } from 'vue-router'; import { useStore } from "vuex"; const route = useRoute(); const router = useRouter(); const store = useStore(); const email = ref(''); const nickname = ref(''); const provider = ref(''); const profileImgUrl = ref(''); const token = ref(''); onMounted(() => { email.value = route.query.email; nickname.value = route.query.nickname; provider.value = route.query.provider; profileImgUrl.value = route.query.profileImgUrl; token.value = route.query.token; if (token.value) { sessionStorage.setItem('accessToken', token.value); } const userInfo = { email: email.value, nickname: nickname.value, provider: provider.value, profileImgUrl: profileImgUrl.value, }; if (userInfo) { sessionStorage.setItem('userInfo', JSON.stringify(userInfo)); } store.commit('setLoginUser', userInfo); router.push('/feed'); }); </script>
Java
복사
이렇게 하면 알맞은 데이터를 받아와 화면 갱신이 가능합니다.

Redirect

HTTP 리디렉션은 일반적으로 클라이언트(일반적으로 웹 브라우저)에게 다른 URL에 대한 새 요청을 생성하도록 지시하는 데 사용됩니다. 리디렉션 응답이 클라이언트로 전송되면 일반적으로 응답 본문이 포함되지 않습니다.

총정리

OAuth2.0 프로토콜을 이용하여 스프링부트에서 SSO 를 구현하였습니다.

로그인 요청 보내기

먼저 GET https://dev.travel-planner.xyz/oauth/authorize/google 으로 소셜로그인 요청을 보냅니다.

로그인 하기

아이디와 비밀번호를 입력하면 아래와 같이 각종 정보와 리다이렉트 주소가 담긴url 로 로그인을 합니다.
https://accounts.google.com/o/oauth2/v2/auth?response_type=code&client_id=…&redirect_uri=https://dev.travel-planner.xyz/oauth/callback

로그인 요청

https://dev.travel-planner.xyz/oauth/callback?state=… 이곳으로 소셜 로그인에 필요한 정보를 쿼리 파라미터에 넣어 구글에 요청합니다.

로그인 성공시

서버에서 로그인 응답으로 받은 유저 정보를 받아 프론트 주소로 수정, 필요한 정보를 리퀘스트 파라미터로 담아 리다이렉트 합니다.
http://localhost:5173/oauth/callback?token=…
 여기서의 토큰은 accesstoken 이며, 파라미터명은 마음대로 정하면 됩니다.