Github OAuth 로그인 구현하기

주리링·2022년 8월 25일
0

우테코 생존기

목록 보기
15/17
post-thumbnail

팀 프로젝트에서 github OAuth를 이용한 로그인을 구현한 과정을 공유합니다.

자세한 코드는 공식 팀의 깃허브에서 확인 하실 수 있습니다.

구현 전 필요한 것

github OAuth app setting

  1. 내 프로필을 선택하고 setting을 누릅니다.

  2. setting 내의 Developer settings -> OAuth Apps ->
    New OAuth App을 선택하여 OAuth App을 만듭니다.

  3. 이 때 나오는 Client ID, Client secrets, 설정한 Authorization callback URL이 Github OAuth 로그인 구현할 때 사용됩니다.
    해당 정보는 보안을 위해 모두 서버에서 관리합니다!

로그인 흐름


1. 사용자가 공식 홈페이지에서 로그인 버튼을 누릅니다. 이 때 클라이언트는 서버로부터 인증할 페이지(github login page)의 url을 요청합니다.

  1. client_id와 redirect_uri으로 구성된 인증할 페이지의 url을 서버에서 클라이언트로 보냅니다. 이를 받은 클라이언트는 사용자를 해당 페이지로 이동하게 합니다.
  2. 사용자가 github 로그인을 시도합니다.
  3. 로그인이 성공했다면 클라이언트로 code가 응답으로 오며, 실패했다면 code가 오지 않습니다.
  4. 클라이언트는 인증을 위해 서버로 code를 보냅니다.
  5. 서버에서 client_id와 client_secret, 클라이언트로 부터 받은 코드를 github 서버로 전송하여 access_token을 받습니다.
  6. github 서버가 올바른 정보가 왔다고 판단이 되면 access_token을 보냅니다.
  7. github 서버로 access_token을 이용하여 유저의 정보를 요청합니다.
  8. 유효한 access_token이 왔다고 판단하면 github 서버에서 유저의 정보를 보냅니다.
  9. 유저의 정보를 통해 인증을 위해 사용될 공식의 access_token을 생성 후 클라이언트로 전송합니다.

OAuth란?

OAuth란 Open Authorization의 약자로 말 그대로 공개되어 있는 인증 방식이다.
회원 가입 절차 자체가 불필요하다고 판단된 경우 다른 서비스의 OAuth를 통해 인증 과정을 생략하기 위해 사용한다.
인증이라하면 로그인이라고 생각하면 쉬울 것 같습니다.

서버측에서 로그인 구현

위의 그림에서 6번인 github서버로 code+client_id+client_secret을 이용하여 github access_token을 요청하는 코드입니다.

private GithubAccessTokenResponse getGithubAccessToken(String code) {
        HttpHeaders headers = new HttpHeaders();
        headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
        headers.add(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE);
        GithubAccessTokenRequest accessTokenRequest = new GithubAccessTokenRequest(clientId, clientSecret, code);

        HttpEntity<GithubAccessTokenRequest> entity = new HttpEntity<>(accessTokenRequest, headers);
        GithubAccessTokenResponse accessTokenResponse = restTemplate.exchange(
                https://github.com/login/oauth/access_token
                HttpMethod.POST,
                entity,
                GithubAccessTokenResponse.class
        ).getBody();

        validateToken(accessTokenResponse);
        return accessTokenResponse;
    }

위의 그림에서 8번인 github access_token을 이용하여 github user의 정보를 요청하는 코드입니다.

private GithubProfileResponse getGithubProfile(GithubAccessTokenResponse accessTokenResponse) {
        String accessToken = accessTokenResponse.getAccessToken();
        String token = TOKEN + accessToken;
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.add(HttpHeaders.AUTHORIZATION, token);
        httpHeaders.add(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE);

        HttpEntity<Void> httpEntity = new HttpEntity<>(httpHeaders);
        GithubProfileResponse profileResponse = restTemplate.exchange(
                https://api.github.com/user,
                HttpMethod.GET,
                httpEntity,
                GithubProfileResponse.class,
                objectMapper
        ).getBody();

        validateProfile(profileResponse);
        return profileResponse;
    }

먼저 저희 공식팀은 RestTemplate를 이용하여 github 서버에 요청을 했습니다.
비동기 방식의 WebFlux도 고려하였지만, 팀원 모두가 아직 적용할 정도로 해당 지식에 대해 알고 있는 것이 아니여서 우선 RestTemplate를 사용하기로 결정했습니다.

이후에는 login 과정에서 github 서버로 요청을 보내는 외부 api를 테스트했던 과정에 대해서 포스팅 하겠습니다!

profile
코딩하는 감자

0개의 댓글