코린이의 개발 일지

[로그인 구현] 깃허브 OAuth 사용해서 로그인 구현 하기 본문

웹 (web)

[로그인 구현] 깃허브 OAuth 사용해서 로그인 구현 하기

폴라민 2022. 10. 2. 02:59
반응형

OAuth

  • 서비스 제공자 (깃허브, 페이스북 등)가 신뢰할 수 없는 타 어플리케이션에게 사용자의 아이디와 패스워드를 제공하지 않더라도 사용자의 특정 정보에 접근하거나 작업을 처리할 수 있도록 하는 방법이자 표준.
  • 웹사이트에서 SNS계정으로 로그인 하는게 대표적인 예이다.
  • 작은 서비스에서 직접 비밀번호를 관리해야 하거나 하는 번거로운 부분을 떠안고 가지 않고 부담을 대기업에게 넘길 수 있다.
  • JSW(Json web Token)와는 다르게 토큰 자체는 큰 의미를 가지고 있지 않다. 즉 토큰 자체가 데이터를 포함하고 있지는 않다. (권한을 확인하고 서비스 제공자에게 데이터를 요청하는 용도)

JSW 란?

  • 유저를 인증하고 식별하기 위한 토큰 기반 인증
  • 토큰 자체에 사용자의 권한 정보나 서비스를 사용하기 위한 정보가 포함된다.

구성요소

client

  • 내가 만든 앱

Resource Owner

  • 내가 만든 앱을 사용할 사용자

Resource Server

  • Resource owner의 개인정보를 가지고 있는 서비스 제공자의 서버

Authorization Server

  • OAuth 엑세스 토큰을 발급 받기 위한 서비스 제공자의 인증 서버

방식

OAuth 의 방식 4가지 중 Code Grant 방식으로 해보자

Code Grant

  1. code를 발급 받고
  2. 발급 받은 code를 사용하여 AccessToken 발급을 위해 다시 한번 인증 서버에 요청

⇒ 여기서 code는 단순한 문자열이다.

동작 과정

  1. 내가 만든 앱(Client) 에서 사용자(Resource Owner) 가 ‘깃허브 로그인하기’ 버튼을 클릭한다.
  2. 사용자가 깃허브에 로그인 되어있지 않은 경우 로그인 요청
  3. Client는 AccessToken을 발급 받기 위한 Code 값을 넣어오기 위해 authorize로 요청
  4. AccessToken 발급을 위해 Code를 파라미터로 넘겨 Authorization Server에 요청
  5. Client에 Github를 통해 로그인한 사용자의 정보를 얻기 위해 AccessToken을 Authorization HTTP Header에 첨부하여 github.com/user에 요청

구현

1. App 등록하기

우선 깃헙에 내 앱을 등록해야한다.

  • developer setting 들어가서 등록

이 callback URL은 인증 완료 후 리다이렉션을 통해 내 앱으로 이동하는데 이때 필요하다. 후에 코드로 자세히 설명하겠다.

2. 코드 구현

우선 순서가 어떻게 되냐면

  1. 내 앱에서 깃허브로 로그인 클릭
  2. 프론트엔드에서 클릭 이벤트 리스너 동작
  3. 이벤트 리스너 내부에서 깃허브 로그인 url로 접속
const url = {
  GITHUB_LOGIN_URL: "<https://github.com/login/oauth/authorize>",
};
window.location.assign(
  url.GITHUB_LOGIN_URL + `?client_id=${clientID.id}`
);

위의 클라이언트 id는 본인 아이디로 해야한다. (app 등록할때 받은 id)

  1. 위 url로 접속하면 깃허브 측에서 위에서 우리가 등록한 callback URL로 리다이렉트 시켜준다.

내 상황에서는

/login/github/callback
  1. 따라서 이 리다이렉트 url get 요청을 받는 부분을 서버에서 코드를 써놔야한다.
app.get("/login/github/callback", (req, res) => {
    // The req.query object has the query params that were sent to this route.
    axios({
      method: "post",
      url: `https://github.com/login/oauth/access_token`,
      headers: {
        accept: "application/json",
      }, //이 부분을 작성하지 않으면 객체형태로 응답을 받지 못한다.(이 부분 작성하지 않은 result를 콘솔로 찍어보니 그냥 문자열 형태...)
      data: {
        client_id: conn.clientID,
        client_secret: conn.clientSecret,
        code: req.query.code,
        //클라이언트가 보낸 POST요청 내 body에서 받아온 authorization code를 가지고
        //authorization server에 access token을 달라고 POST요청을 보낸다
      },
    }).then((response) => {
      const access_token = response.data.access_token;
      res.redirect("/success" + `?access_token=${access_token}`);
    });
  });

이 리다이렉트 get요청을 받으면 url 뒤에 쿼리로 code=”~~~~” 이런식으로 code가 붙어있는데,

이 code값이랑

내 client_id,

내 client_server 값을

data에 넣어서 post 요청을 보내야한다.

나머지는 똑같이 작성하면 된다.

  1. Post 요청 응답을 받으면 아래의 url로 access_token 값을 headers에 넣어서 get 요청을 보내야한다.
`https://api.github.com/user`

코드

app.get("/success", function (req, res) {
    axios({
      method: "get",
      url: `https://api.github.com/user`,
      headers: {
        Authorization: "token " + req.query.access_token,
      },
    }).then((response) => {
      console.log(response.data);
      // 회원가입 되어있는지 확인.
      // 로그인 사용자 정보 세션 저장.
      res.redirect("/");
    });
  });
  1. 최종 응답을 받으면 response.data에 로그인 정보가 들어가 있다. 이걸로 로그인 정보 처리해준 후에 내 원래 main 주소로 redirect 시키면 로그인이 완료된다.

참고:

OAuth 사용법

https://www.loginradius.com/blog/engineering/oauth-implemenation-using-node/

https://velog.io/@devjade/OAuth-authentication-구현하기github-로그인

https://pronist.dev/144

공식 문서

https://docs.github.com/en/developers/apps/building-oauth-apps/authorizing-oauth-apps#device-flow

redirect보낼 때 data 같이 보내기

https://burning-camp.tistory.com/22

참고 사항 : server에서 fetch is not defined 오류 날때

fetch가 브라우저에서 사용 되는 것이라서 쉘에서 사용할 때는 아래를 추가해주면 된다.

npm install node-fetch

import fetch from "node-fetch"

참조:

https://www.pabburi.co.kr/content/javascript/nodejs-referenceerror-fetch-is-not-defined-오류가-발생/

반응형
Comments