팀 프로젝트에서 github OAuth를 이용한 로그인을 구현한 과정을 공유합니다.
자세한 코드는 공식 팀의 깃허브에서 확인 하실 수 있습니다.
내 프로필을 선택하고 setting을 누릅니다.
setting 내의 Developer settings -> OAuth Apps ->
New OAuth App을 선택하여 OAuth App을 만듭니다.
이 때 나오는 Client ID, Client secrets, 설정한 Authorization callback URL이 Github OAuth 로그인 구현할 때 사용됩니다.
해당 정보는 보안을 위해 모두 서버에서 관리합니다!
1. 사용자가 공식 홈페이지에서 로그인 버튼을 누릅니다. 이 때 클라이언트는 서버로부터 인증할 페이지(github login page)의 url을 요청합니다.
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를 테스트했던 과정에 대해서 포스팅 하겠습니다!