Skip to content

Oauth Flow

yhh1056 edited this page Oct 7, 2022 · 1 revision

Oauth2.0 및 github oauth 적용하기

OAuth2.0

인증을 위한 표준 프로토콜

버전별 설명 링크

[OAuth1 란](https://wan-blog.tistory.com/20)

Oauth 2.1, 2.0에 대한 취약점 알고 있기

[OAuth 란 무엇인가?](https://www.ssemi.net/what-is-the-oauth2/)

땡쿠의 OAuth - 1

[https://accounts.google.com/o/oauth2/v2/auth?client_id=135992368964-20ad4ul4e3mmia6iok3r9dpg6bshp4uq.apps.googleusercontent.com&redirect_uri=http://localhost:8080/api/callback&response_type=code&scope=https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile openid](https://accounts.google.com/o/oauth2/v2/auth?client_id=135992368964-20ad4ul4e3mmia6iok3r9dpg6bshp4uq.apps.googleusercontent.com&redirect_uri=http://localhost:8080/api/sign-in/callback&response_type=code&scope=https://www.googleapis.com/auth/userinfo.email)
  1. 위의 로그인 요청 페이지 url로 요청을 보낸다. (프론트)
    • client_id : 땡쿠의 로그인 서비스인지 판별하는 식별자
    • redirect_url : 로그인 성공 후 리다이렉션 되는 url
    • response_type : 반환 타입
    • scope : access_token에서 부여하는 접근 범위, 공백으로 구분
  2. redirect_url(localhost:3000/auth/redirection?code={code})를 받는다. (프론트)
  3. code를 /api/sign-in?code={code} API로 요청한다.
    1. 프론트에서 넘어온 code와 WAS에 있는 property 값으로 구글에게 accessToken을 받아온다. (clientSecret이 있는 이유)
    2. accessToken을 다시 구글 회원 조회 API로 보내서 구글 회원 정보(socialId, email, profileUrl)를 가져온다.
  4. 회원 정보를 바탕으로 가입된 유저인지, 신규유저인지 판단하고 땡쿠의 accessToken을 만들어 반환한다.

땡쿠의 OAuth - 2 (OpenID Connect)

OpenId는 OAuth 2.0 프로토콜 위에 있는 ID 계층이다. 사용자의 정보를 확인할 수 있고 REST와 유사한 방식으로 사용자에 대한 기본 프로필 정보를 얻을 수 있다.

[OAuth 그리고 OpenID Connect](https://6991httam.medium.com/oauth%EB%9E%80-%EA%B7%B8%EB%A6%AC%EA%B3%A0-openid-8c46a65616e6)

땡쿠의 가입절차로 OIDC 방식을 사용해도 문제가없다. 오히려 기존 방식은 구글 API를 2번호출하는데 이를 1번으로 줄일 수 있다. (리소스 절약)

[OpenID Connect | Google Identity | Google Developers](https://developers.google.com/identity/protocols/oauth2/openid-connect)

1, 2번은 동일하다.

  1. code를 /api/sign-in?code={code} API로 요청한다.
    1. 프론트에서 넘어온 code와 WAS에 있는 property 값으로 IdToken을 요청한다.

      private GoogleTokenResponse requestGoogleToken(final HttpEntity<MultiValueMap<String, String>> entity) {
          return restTemplate
                  .exchange(tokenRequestUrl,
                          HttpMethod.POST,
                          entity,
                          GoogleTokenResponse.class)
                  .getBody();
      }
    2. idToken은 JWT 토큰이다. payload를 꺼내서 계정 정보를 가져온다. (sub, email) *sub : 사용자 식별자

  2. 회원 정보를 바탕으로 가입된 유저인지, 신규유저인지 판단하고 땡쿠의 accessToken을 만들어 반환한다.

땡쿠의 OAuth flow - 3 (닉네임을 등록해야 가입 완료)

기존 방식은 OAuth 로그인에 성공하면 가입유무 상관없이 무조건 회원으로 가입된다. 닉네임을 반드시 설정해야된다는 정책이 추가됨에 따라 닉네임이 등록되기 전까지 구글 로그인에 성공하여도 가입상태가 아니여야한다.

여러 방법이 존재했다.

  1. 가입 유무 칼럼을 만들어 관리
  2. 새로운 테이블에 데이터를 쌓아두고 관리
  3. openId를 프론트와 한번 더 주고받기

1, 2번의 경우 회원 가입을 위해 데이터베이스와 통신해야 하고 휘발성 데이터에 대한 관리가 필요했다. 디비를 사용하기 때문에 3번 방식보다는 더 안전하다는 생각이 든다. 땡쿠팀의 경우 데이터베이스를 관리하는 리소르를 줄이면서도 보안적으로 괜찮은 3번방식을 선택했다. 실제 velog도 3번 방식을 사용하는 걸 확인했다.

로그인시 응답으로 가입여부와 토큰을 추가적으로 응답하면서 회원가입 요청을 받을 때 헤더에 idToken을 받음으로써 회원가입이 완료되도록 처리했다.