본문 바로가기
개발/React

리액트, Node JS - 인증 토큰 획득 서버 구현하기 (GitHub Access Token Server with Node JS)

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

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

 

리액트 전체 링크

Node JS 전체 링크

 

참고

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

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

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

 

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

 

리액트에서 client secret은 더 이상 필요 없으므로, (보안상 들고 있어서도 안된다.) .env에서 삭제한다.

 

.env

REACT_APP_CLIENT_ID=af98b4a2c8aff18122d7

Node JS 서버 구축

 

Node에서 .env를 사용하기 위해서는 dotenv를 설치해야 한다.

$ npm install dotenv

 

설치 후 Node의 .env에 아래와 같이 client secret 을 추가하자.

CLIENT_SECRET=7...bb595e

 

사용 방법은 아래와 같다.

const dotenv = require('dotenv');

...

dotenv.config();
console.log(process.env.CLIENT_SECRET);

 

이전 글에서 CORS가 발생했던 RESTful API를 routes/githubLogin.js에 구현한다.

const axios = require("axios");
const express = require("express");
const router = express.Router();
const dotenv = require('dotenv');

const getResponse = async (code, clientID) => {
  dotenv.config();
  const response = await axios.post(
    "https://github.com/login/oauth/access_token",
    {
      code,
      client_id: clientID,
      client_secret: process.env.CLIENT_SECRET, 
    },
    {
      headers: {
        accept: "application/json",
      },
    }
  );

  return response;
};

router.get("/", async (req, res) => {
  let code = req.query.code;
  let clientID = req.query.clientID;
  let response = await getResponse(code, clientID);
  
  console.log(response.data.access_token);

  res.send({token: response.data.access_token});
});

module.exports = router;

 

리액트에서 로그인 요청을 하면 access token을 정상적으로 얻을 수 있다.

 

전체 코드는 아래를 참고하자.


인증 토큰으로 인증 정보 획득하기

 

Node 서버가 완성되었으므로, 리액트getAccessToken을 수정하자.

 

token을 이용하면 아래의 API로 유저 정보를 얻을 수 있다.

https://api.github.com/user

 

아래와 같이 코드를 수정해보자.

여기서는 로그인 프로필을 변경하기 위한 avatarUrl누가 로그인 했는지 알기 위해 loginID만 로그를 추가하였다.

const getAccessToken = async (code) => {
  let server = `http://192.168.55.120:3002`;
  let accessInfo = await axios.get(
    `${server}/githubLogin?code=${code}&clientID=${clientID}`
  );

  let token = accessInfo.data.token;

  const userResponse = await axios.get("https://api.github.com/user", {
    headers: {
      Authorization: `Bearer ${token}`,
    },
  });

  const userData = userResponse.data;
  const avatarUrl = userData.avatar_url;
  const loginID = userData.login;
  
  console.log(userData);
  console.log(avatarUrl);
  console.log(loginID);
};

 

실제 avatarUrl을 클릭해보면 깃허브에 설정한 프로필 이미지가 보이게 된다.

 

이를 활용하여 로그인 프로필을 변경할 수 있다.

여기에서는 localStorage에 해당 정보들을 미리 추가해두기만 하자.

    const userData = userResponse.data;
    const avatarUrl = userData.avatar_url;
    const loginID = userData.login;

    console.log(userData);
    console.log(avatarUrl);
    console.log(loginID);

    localStorage.setItem("GITHUB_TOKEN", token);
    localStorage.setItem("AVATAR_URL", avatarUrl);
    localStorage.setItem("LOGIN_ID", loginID);
  };

전체 코드는 다음과 같다.

 

Node JS

 

routes/githubLogin.js

const axios = require("axios");
const express = require("express");
const router = express.Router();
const dotenv = require('dotenv');

const getResponse = async (code, clientID) => {
  dotenv.config();
  const response = await axios.post(
    "https://github.com/login/oauth/access_token",
    {
      code,
      client_id: clientID,
      client_secret: process.env.CLIENT_SECRET, 
    },
    {
      headers: {
        accept: "application/json",
      },
    }
  );

  return response;
};

router.get("/", async (req, res) => {
  let code = req.query.code;
  let clientID = req.query.clientID;
  let response = await getResponse(code, clientID);
  
  console.log(response.data.access_token);

  res.send({token: response.data.access_token});
});

module.exports = router;

 

server.js

const express = require("express");
const app = express();

const cors = require("cors");
app.use(cors());

const githubLogin = require("./routes/githubLogin");

app.use("/githubLogin", githubLogin);

app.listen(3002, () =>
  console.log("Node.js Server is running on port 3002...")
);

 

React

 

page/GitHubLoginCallback.js

import React, { useEffect } from "react";

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

const clientID = process.env.REACT_APP_CLIENT_ID;

const GitHubLoginCallback = () => {
  const getAccessToken = async (code) => {
    let server = `http://192.168.55.120:3002`;
    let accessInfo = await axios.get(
      `${server}/githubLogin?code=${code}&clientID=${clientID}`
    );

    let token = accessInfo.data.token;

    const userResponse = await axios.get("https://api.github.com/user", {
      headers: {
        Authorization: `Bearer ${token}`,
      },
    });

    const userData = userResponse.data;
    const avatarUrl = userData.avatar_url;
    const loginID = userData.login;

    console.log(userData);
    console.log(avatarUrl);
    console.log(loginID);

    localStorage.setItem("GITHUB_TOKEN", token);
    localStorage.setItem("AVATAR_URL", avatarUrl);
    localStorage.setItem("LOGIN_ID", loginID);
  };

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

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

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

export default GitHubLoginCallback;
반응형

댓글