Github OAuth2 적용하기

귀찮Lee·2022년 10월 4일
0

MOCCO Project (22.09~10)

목록 보기
3/5
post-custom-banner

◎ OAuth2 적용 방법

◎ Github 연동 구현 방법 & 이유

  • Github 연동 구현 이유

    • 가장 먼저 구현하고자 하는 기능은 현재 회원가입한 사용자가 Github를 연동하여 Github 사용자 정보를 가져오고 저장하는 것이 목표였다.
    • Spring Security를 이미 채용했기 때문에 이를 이용하려 했지만, 일반적인 연동 부분은 따로 구현이 안되어 있는 것 같아 다른 방법을 생각했다.
    • Spring Security를 이용하지 않고 Authorization Code Grant 방법을 구현하는 것을 멘토님이 추천하여 해당 방식으로 구현함
  • Github 연동 구현 방법

    • 이번에 구현한 프로젝트는 CSR(Client Side Rendering) 방식으로 이루어져 있어 Authorization Code Grant 방식을 Client(React)와 Server(Spring)에서 하는 역할을 일부 나누었다.

    • Step1 : React에서 Github(Authorization Server)에 authorization code요청

      • Client(React)에서 Github에 요청
      • 유저에게 해당 사이트에 Github 정보를 주는 것을 허용할지 확인함 (특정 페이지로 리다이렉트)
      • 허용시 authorization code를 받고, 이것을 Server(Spring)으로 값을 전달함
    • Step2 : Spring에서 Github(Authorization Server)에 access token을 요청 (httpclient, gson 패키지를 이용)

          private String takeAccessToken(String authorizationCode)
                  throws URISyntaxException, IOException {
      
              HttpPost httpPost = new HttpPost();
      
              httpPost.addHeader("Accept", "application/json");
              httpPost.addHeader("Content-Type", "application/json");
      
              URI uri = new URIBuilder("https://github.com/login/oauth/access_token").build();
              httpPost.setURI(uri);
              httpPost.setConfig(getRequestConfig());
      
              GithubRestClientDto.Request request
                      = new GithubRestClientDto.Request(clientId, clientSecret, authorizationCode);
              httpPost.setEntity(new StringEntity(gson.toJson(request)));
      
              HttpClient httpClient = HttpClientBuilder.create().build();
              HttpResponse httpResponse = httpClient.execute(httpPost);
      
              String resultJson = EntityUtils.toString(httpResponse.getEntity());
              GithubRestClientDto.Response response  = gson.fromJson(resultJson, GithubRestClientDto.Response.class);
      
              if (response.getAccess_token() == null){
                  throw new BusinessLogicException(ExceptionCode.NOT_NORMAL_AUTHORIZATION_CODE);
              }
              return response.getAccess_token();
      
          }
    • Step3 : Github(Resource Server)에 유저 정보를 요청함

          private GithubRestClientDto.UserInfo getGithubInfo(String accessToken) throws IOException {
      
              HttpGet httpGet = new HttpGet("https://api.github.com/user");
              httpGet.addHeader("Authorization","Bearer " + accessToken);
              httpGet.setConfig(getRequestConfig());
      
              HttpClient httpClient = HttpClientBuilder.create().build();
              HttpResponse httpResponse = httpClient.execute(httpGet);
      
              String resultJson = EntityUtils.toString(httpResponse.getEntity());
              GithubRestClientDto.UserInfo response  = gson.fromJson(resultJson, GithubRestClientDto.UserInfo.class);
      
              response.setProvider(clientId);
              return response;
          }

◎ Github 로그인 방법 & 이유

  • Github 로그인 방법 선택 이유

    • Spring Security에서 OAuth2 로그인 필터를 따로 지원하므로 이를 이용하여 로그인 할 수 있다.
    • 이를 이용하여 로그인 할 수 있었으나 Client Side Rendering에서 따라오는 여러가지 이슈(특히 CORS)들이 일어남
    • 지금 진행하는 프로젝트는 기간이 정해져 있었고, Client 담당자도 여기에 신경써줄 여력이 안되어 Spring Security를 이용하지 않고, Github 연동과 방법을 이용함
  • Github 로그인 방법

    • React에서 Github(Authorization Server)에 authorization code요청
    • Spring에서 이미 만들어 놓은 메서드를 통해 Github 정보를 가져옴
    • DB에서 Github 식별자와 일치하는 유저를 가져옴
    • 이후, 로그인 과정을 진행 (JWT, Session ...)

◎ 추후 개선 방향

  • 아직 연동이 되지 않은 계정의 경우 오류를 전달하는데, 자동으로 회원가입이 될 수 있게 수정해야 할 필요 있음.

◎ 참고 자료

profile
배운 것은 기록하자! / 오류 지적은 언제나 환영!
post-custom-banner

0개의 댓글