소셜로그인에 다양한 방법이 있지만 프론트, 백엔드 통합 부분으로 정리를 해보고자한다.
나중에 소셜로그인을 하게된다면 이 정리를 보고 다시 할 수 있을 정도로 정리해보자.
우선 구글로그인 하나만 해도 나머진 할 수 있으니까 구글로만 정리를 해보려고한다.
우선 구글 개발자 콘솔에 들어가야한다.
https://console.cloud.google.com/
API 만드는데 들어가서 "OAuth 동의 화면"를 들어간다.
그 뒤 웹페이지 클라이언트를 만들어서 안에 들어가보면 다음과 같이 있을거다.
승인된 JavaScript 원본
승인된 리디렉션 URI
승인된 JavaScript 원본
여기에는 내가 사용하는 프로젝트의 주소, 아니면 테스트할 로컬 주소를 입력하면된다.
나의 경우는 https://www.livflow.co.kr, http://localhost:5173
이렇게 2개를 입력해주면 된다.
승인된 리디렉션 URI
로그인 이후에 올 페이지 엔드포인트를 적어주면된다.
http://localhost:5173/auth/login/callback/google
이런식으로 해두었다.
이제 소셜로그인의 플로우를 봐보자
[사용자] → (로그인 버튼 클릭)
↓
[프론트엔드] → (구글 인증 서버로 리디렉션)
↓
[구글 로그인 완료] → (인가 코드 발급)
↓
[프론트엔드] → (인가 코드 백엔드로 전송)
↓
[백엔드] → (인가 코드로 액세스 토큰 요청)
↓
[구글] → (액세스 토큰 + 사용자 정보 반환)
↓
[백엔드] → (JWT 발급 + Redis에 리프레시 토큰 저장)
↓
[프론트엔드] ← (액세스 토큰 쿠키로 전달)
↓
[사용자 로그인 완료 🚀]
구글 인증서버는 이런 주소를 쓴다.
https://accounts.google.com/o/oauth2/v2/auth
그럼 여기로 가서 사용자가 구글로그인을 성공하면 인가코드가 나온다.
그럼 인가코드를 백엔드로 전송해서 해당 함수에 넣어야한다 .
class GoogleAuth(APIView):
authentication_classes = []
permission_classes = [AllowAny]
def post(self, request, *args, **kwargs):
code = request.data.get("code")
token_endpoint = "https://oauth2.googleapis.com/token"
data = {
"code": code,
"client_id": os.getenv("GOOGLE_CLIENT_ID"),
"client_secret": os.getenv("GOOGLE_CLIENT_SECRET"),
"redirect_uri": os.getenv("GOOGLE_REDIRECT_URI"),
"grant_type": "authorization_code",
}
만약 이 엔드포인트가
www.api.liv/google/login/callback/
이런식이라고 보면
프론트 엔드에서는 이 엔드포인트로 인가코드를 전달해야한다.
그럼 Googleauth라는 함수에서
"code": code,
이 부분에서 인가코드를 받고 구글 개발자 콘솔에 있는 client_id, client_secret, redirect_uri 이 부분을 https://oauth2.googleapis.com/token 이 주소로 보내게 된다.
그럼 코드와 id, secret, uri가 모두 일치한다면
구글에서는 액세스 토큰과 리프레시 토큰을 재발급해준다.
그럼 이 토큰을 가지고
https://www.googleapis.com/oauth2/v2/userinfo
이 엔드포인트에 보내 원하는 유저 정보를 받아온다.
그 뒤 해당 정보를 가지고 백엔드 jwt에서 자체적으로 토큰을 제작한다 .
이 이름도 액세스토큰, 리프레시 토큰이다.
그럼 이제 소셜로그인을 통해
유저 정보와 jwt 액세스토큰, 리프레시 토큰이 생성된다.
그 뒤에 토큰 관리방법은 다양한 방법이 있어서 선택하면되지만
리프레시 토큰의 생명주기가 긴 만큼 보안이 확실하게 관리하고
액세스 토큰은 세션에서 관리하는게 편할 듯 하다.