본문 바로가기
개발/React

리액트 - 깃허브 OAuth 콜백 처리하기 (GitHub OAuth Callback)

by 피로물든딸기 2023. 8. 19.
반응형

깃허브 데스크탑으로 프로젝트 관리하기 강의 오픈!! (인프런 바로가기)

 

리액트 전체 링크

 

참고

- 깃허브 OAuth Access 토큰 발급 받기

- Toast UI 에디터로 깃허브 마크다운 저장하기

- URL query string 받아오기

- 리덕스로 로그인 상태 관리하기

 

GitHub OAuth Project Settings
Material UI로 깃허브 로그인 프로필 만들기
깃허브 OAuth 콜백 처리하기
인증 토큰 획득 서버 구현하기
인증 토큰으로 로그인 상태 관리하기
로그인 정보를 활용하여 Commit Message 남기기
새 창으로 로그인해서 현재 상태 유지하기

 

깃허브 OAuth 토큰을 발급 받고 .env까지 설정해두자.

(실제 환경에서 토큰은 서버를 통해 얻어야 한다.)

 

인증을 요청하게 되면 깃허브 OAuth Apps에서 설정한 callback URL로 이동하게 된다.

 

먼저 callback page를 아래와 같이 간단히 만들자.

 

page/GitHubLoginCallback.js

import React from 'react';

const GitHubLoginCallback = () => {
  return (
    <div>
      CallBack!
    </div>
  );
};

export default GitHubLoginCallback;

 

App.js의 라우터에 callback 페이지를 추가한다.

  <Routes>
    <Route path="/" element={<Home />} />
    <Route path="/editor" element={<SimpleToastEditor />} />
    <Route path="/callback" element={<GitHubLoginCallback/>} />
  </Routes>

 

GitHubLoginButton.js에서 hrefloginURL을 추가한다.

loingURL OAuth Apps에서 발급받은 clientIDcallback URL이 필요하다.

...

const clientID = process.env.REACT_APP_CLIENT_ID;
const callbackURL = "http://localhost:3000/callback";
const loginURL = 
  `https://github.com/login/oauth/authorize?client_id=${clientID}&scope=repo:status read:repo_hook user:email&redirect_uri=${callbackURL}`;

const GitHubLoginButton = () => {
  return (
    <div>
      <Box sx={{ m: 2 }}>
        <Stack direction="row" spacing={2}>
          <Avatar alt="GitHub Login" src="/static/images/avatar/1.jpg" />
          <Button
            variant="outlined"
            color="secondary"
            href={loginURL}
          >
            로그인
          </Button>
        </Stack>
      </Box>
    </div>
  );
};

export default GitHubLoginButton;

 

이제 로그인 버튼을 눌러보자.

 

아래와 같이 설정한 URL로 이동되고 Authorize bloodstrawberry 버튼을 누르면 코드를 받아올 수 있다.

 

callback 라우터에 query string으로 code가 추가된 것을 알 수 있다. (참고 code는 매번 변경된다.)

 

위의 code를 얻기 위해 query-string과 axios를 설치하자.

npm install query-string
npm install axios

 

이제 callback 페이지가 실행되면 useEffect에서 code를 얻어보자.

import React, { useEffect } from 'react';

import axios from "axios";
import queryString from 'query-string'; 

const clientID = process.env.REACT_APP_CLIENT_ID;
const callbackURL = "http://localhost:3000/callback";
const loginURL = 
  `https://github.com/login/oauth/authorize?client_id=${clientID}&scope=repo:status read:repo_hook user:email&redirect_uri=${callbackURL}`;

const GitHubLoginCallback = () => {
  const getCode = () => {
    let qs = queryString.parse(window.location.search);
    let code = qs.code;
  
    console.log(code);
  }

  useEffect(() => getCode(), []);

  return (
    <div>
      CallBack!
    </div>
  );
};

export default GitHubLoginCallback;

 

정상적으로 code를 얻는 것을 알 수 있다.


인증 토큰 획득과 CORS 에러

 

아래의 URL을 POST로 code, client ID, client secret과 함께 RESTful API로 보내면, 인증 토큰을 얻는다.

 https://github.com/login/oauth/access_token

 

getCode를 아래와 같이 수정하자.

  const getAccessToken = async (code) => {
    const clientSecret = process.env.REACT_APP_CLIENT_SECRET;
    const response = await axios.post(
      "https://github.com/login/oauth/access_token",
      {
        code,
        client_id : clientID, // SAFU application의 정보
        client_secret : clientSecret, // SAFU application의 정보
      },
      {
        headers: {
          accept: "application/json",
        },
      }
    );
    
    // ...
  }

  const getCode = () => {
    let qs = queryString.parse(window.location.search);
    let code = qs.code;
    getAccessToken(code);
  }

  useEffect(() => getCode(), []);

 

.env를 이용하려면 다시 bulid를 해야 한다. (npm run build)

 

client secret은 보안 때문에 공개되어서는 안되는 토큰이다.

그래서 CORS로 같은 Application에서 위의 API를 사용하지 못하도록 한다.

 

CORS 에러를 해결하기 위해, 다음 글에서 인증 토큰을 얻기 위해 Node 서버를 구축해보자.

반응형

댓글