GitHub Login 따라해보기

이기훈·2021년 1월 12일
0

OAuth 구현하기 (GitHub)

OAuth란?

A 서비스를 사용할 경우, 별도의 회원가입 없이 로그인을 제공하는 플랫폼이 있으면 해당 서비스를 사용할 수 있도록 해주는 하는 프로토콜을 말한다.

OAuth 배경

OAuth 방식이 등장하기 전에는 Third party 어플리케이션에서 구글 등의 id/password를 이용해 직접 로그인하여 사용했기 때문에 보안에 취약한 문제점을 해결하기 위해 트위터 개발자와 Gnolia의 개발자가 만들어낸 인증 방식

OAuth 적용

1. GitHub에서 OAuth App 설정 (Client ID와 Client Secret을 확인)

2. callback URL 설정

  • callback URL을 리액트에서 code를 받을 페이지로 설정해야 한다.

3. GitHub버튼 생성 및 OnClick 이벤트 적용

// process.env.DEV_CLIENT_ID : gitHub Client ID 
// process.env.CALLBACK_URL : gitHub callback URL  
const githubOnClick = () => {
    window.location.href = `https://github.com/login/oauth/authorize?client_id=${process.env.DEV_CLIENT_ID}&redirect_uri=${process.env.CALLBACK_URL}`;
  };
<button onClick={githubOnClick}>GitHub Login</button>
  • GitHub 버튼 클릭시, GitHub 유저 인증페이지로 이동하고 난 뒤, GitHub 로그인이 성공하면 Callback URL로 Code를 첨부해 이동시킨다.

4. Callback Page 작성

import React, { useEffect } from 'react';
import { useLocation, useHistory } from 'react-router-dom';
import { UserDispatch } from '../../../../App';

const Callback = () => {
  const searchParams = new URLSearchParams(useLocation().search);
  const code = searchParams.get('code');
  const dispatch = useContext(UserDispatch);
  const history = useHistory();

  const getHitHubLogin = async (code) => {
    fetch('http://127.0.0.1:4000/user/github', {
      method: 'post',
      headers: {
        Accept: 'application/json',
        'Content-Type': 'application/json',
      },
      mode: 'cors',
      credentials: 'include',
      body: JSON.stringify({
        code,
      }),
    }).then((res) => {
      history.push('/picker');
      dispatch({ type: 'SET_IS_LOGINED', payload: true });
    });
  };

  useEffect(() => {
    getHitHubLogin(code);
  });

  return <div />;
};

export default Callback;
  • URL에 들어있는 code를 useLocation Hook을 통해 추출한 뒤, fetch를 사용해 user/github API로 code를 전송하는 로직 및 picker 페이지로 이동

5. Local Server에서 API 작성 및 Access Token을 가져와서 해당 유저의 GitHub 프로필 정보 받아오기

router.post('/github', async (req, res) => {
  const { code } = req.body;
  const clientId = process.env.DEV_CLIENT_ID;
  const secret = process.env.DEV_CLIENT_SECRET;

  const { data } = await axios.post(
      'https://github.com/login/oauth/access_token',
      {
        code,
        client_id: clientId,
        client_secret: secret,
      },
      {
        headers: {
          accept: 'application/json',
        },
      },
  );
  const searchParams = new URLSearchParams(data);
  const accessToken = searchParams.get('access_token'); 
  
  const USER_PROFILE_URL = 'https://api.github.com/user';

  const { data: userInfomation } = await axios.get(USER_PROFILE_URL, {
    headers: {
      Authorization: `token ${accessToken}`,
    },
  });

  res.json(userInfomation);

});
  • Github으로 CliendID, SECRET, Code 정보를 사용해 access Token 받아오고, 다시 Github에 API 요청을 해 프로필 정보를 받아온다.

6. 받아온 GitHub 정보를 이용해 회원가입 및 로그인 진행

const existId = await userModel.findOne({
  userId: userInfomation.login + userInfomation.id,
});

if (existId) {
  req.session.user = existId;
  res.status(200).json(true);
  return;
}

const User = await userModel.create({
  userId: userInfomation.login + userInfomation.id,
  nickname: userInfomation.login,
  email: userInfomation.email,
});

req.session.user = User;
res.status(200).json(true);
  • GitHub정보를 이용해 회원가입 및 로그인을 진행한다. 만약 DB에 GitHub 회원가입이 되어있다면, express-session을 사용해 세션 및 쿠키에 로그인 정보를 저장하고, 되어있지 않다면 DB에 데이터를 넣어준 뒤 로그인 정보를 저장한다.

참고

0개의 댓글