woowacourse-teams / 2024-code-zap

코드 템플릿, Zap싸게 저장하고! Zap싸게 공유하자! 코드잽 ⚡
https://www.code-zap.com
24 stars 8 forks source link

[FEAT] OAuth 사용자 인증 도입 #794

Open zangsu opened 1 month ago

zangsu commented 1 month ago

📌 어떤 기능인가요?

OAuth 2.0 을 사용한 사용자 인증을 도입한다.

회의를 통해 #779 작업을 OAuth 도입으로 전환

📜 작업 상세 내용

⏳ 예상 소요 시간 (예상 해결 날짜)

5일 소요 (10/20 15:00)

zangsu commented 1 month ago

OAuth 의 로그인 동작 간단 설명!

OAuth 는 3자의 통신 과정으로 진행됩니다.

통신 참여 대상:

  1. 만두가 OAuth 로그인을 선택
  2. 코드잽은 구글 로그인 창을 제공해 줍니다.
  3. 만두가 구글에 로그인 요청을 보냅니다.
  4. 구글은 만두에게 Authorization Code (임시 비밀번호라고 생각하면 됩니다.) 를 발급해 주며 코드잽으로 리다이렉션 시킨다.
  5. 만두는 코드잽의 정해진 URL 로 리다이렉션을 하면서 Authorization Code 를 코드잽에게 알려준다.
  6. 코드잽은 구글에게 Authorization Code를 전달하고 Access Token 을 발급받는다.

Access Token 은 코드잽이 구글에게 유저 정보를 조회 (또는 다른 작업) 하기 위해 존재한다고 하네요~ (저는 처음에 만두가 코드잽에 접근하기 위해 사용하는 줄 알았음 ㅎㅎ 그게 아니래용~)

그럼 우리는??

위의 설명에서는 프론트엔드와 백엔드가 뭉뚱그려 설명되어 있는데요. 우리는 프론트의 역할과 백엔드의 역할이 엄연히 구분되어야 합니다. 이에 대해서는 조금 더 이야기를 해 보아야 겠지만, 선배 기수인 후디의 블로그 글을 참고해 볼 수 있을 것 같아요~

참고 자료

깃짱의 OAuth 2.0의 개념과 과정

zangsu commented 1 month ago

로그인 유지 방법

로그인을 할 때는 Access Token 을 사용하더라도, 로그인을 유지할 때는 지금과 동일하게 CredentialManager, CredentialProvider 를 통해 쿠키 값을 지정할 수 있을 것 같습니다.

이렇게 하면 Access Token 을 서버에 저장할 필요 없이 기존 방식대로 로그인 유지가 가능합니다.

zangsu commented 1 month ago

DB 변경

OAuth 에서는 기본적으로 제공해 주는 사용자의 고유 ID 만을 사용할 계획입니다.

새로 생길 테이블 :

(fk) member_id identify_id
1 01021

-> 01021 이라는 고유 ID 는 1번 멤버로 식별 가능한 값이다.

테이블이 하나가 추가되면 다른 OAuth 서비스를 추가로 확장하더라도 기존 테이블의 변경이 없기에 롤백이 쉽습니다. 또한, OAuth 서비스가 늘어나면서 특정 테이블이 비대해 질 불편함도 예방할 수 있습니다.

zangsu commented 1 month ago

고려 사항

OAuth 관련해서 알아보다가 방끗에서 받은 피드백을 알게 되어 공유드려요! OAuth 를 하나만 사용하면 해당 OAuth 서비스에 강한 의존성이 생깁니다. (ex. 카카오 서비스가 문제가 생기면 카카오 로그인을 사용하는 사람이 서비스 자체를 이용하지 못함)

그래서 OAuth 도 두 개 이상 붙이는 것이 권장되며, 일반 로그인도 함께 제공하는 이유가 이렇다고 해요. (아마 티스토리는 그 자체가 카카오에서 제공하는 서비스라서 카카오 로그인만 사용하게 하는 것 같기도??)

오늘 결정되었던 "Google 하나만 붙이고 일반 로그인은 점차 줄여나가자" 라는 방향에 대한 문제인 것 같아서 일단 공유 드립니다.

일반 로그인을 그대로 유지한 채로 나중에 여유가 생기면 Email 인증을 추가로 넣는 방법은 어떠실까요? 일반 회원가입은 코드를 삭제하지 않고 잠시 숨겨두었다가 다시 살리면 좋을 것 같은데요. Email 인증도 제가 욕심이 나서 제안 하는 것이라 "작업 강도" 가 걱정이라면 제가 구현해도 좋으니 편하게 정책적으로만 의견 주시면 감사하겠습니다~

zangsu commented 3 weeks ago

로그인 및 회원가입 플로우

회원가입

로그인

첫 로그인

  1. 사용자가 구글 로그인을 합니다. 이 과정에서 Credential Code 가 사용자에게 전달됩니다.
  2. 사용자의 브라우저는 미리 제공된 프론트엔드의 페이지로 리다이렉트 되고, 프론트엔드에서 Credential Code 를 가집니다.
  3. 프론트엔드에서 미리 제공된 백엔드의 API 로 Credential Code 를 전달합니다.
  4. 백엔드에서 구글로 Credential Code 를 사용해 요청을 보내 구글의 사용자 식별자를 얻습니다.
  5. 백엔드에서 "직접" Access Token / Refresh Token 을 생성합니다.
  6. 사용자에게 Access Token 을 전달합니다. (쿠키 사용 예정)

로그인 유지

  1. 사용자는 서버에게 제공받은 Access Token 을 사용해 요청을 보냅니다.
  2. 서버는 토큰을 읽어 사용자를 인증합니다.

토큰 재발급

  1. 사용자는 서버에게 제공받은 Access Token 을 사용해 요청을 보냅니다.
  2. 토큰이 만료된 경우 서버는 사용자에게 "토큰이 만료됨" 을 알 수 있는 응답을 보냅니다.

    1. 응답은 Oauth 2.0 표준에 따라 다음의 형태를 가집니다.
      
      HTTP/1.1 401 Unauthorized
      WWW-Authenticate: Bearer error="invalid_token" error_description="The access token expired"
      Content-type: application/json

    { "error": "invalid_token", "error_description": "The access token expired" }

  3. 사용자는 토큰 재생성 요청을 보냅니다.
  4. 서버는 저장하고 있던 Refresh Token 을 확인 후 사용자에게 새로운 Access Token 을 전달합니다.
zangsu commented 1 week ago

AccessToken 전달 방식

Cookie의 동작은 브라우저에 의존합니다. 이에 Cookie 대신 HTTP 헤더를 사용하여 AccessToken을 전달합니다.