티스토리 뷰

반응형

구글 로그인, 카카오 로그인과 같이 깃헙으로 로그인 하는 방법에 대해 알아보도록 하자. 개념 정리보다는 react를 통해 빠르게 구현할 수 있도록 핵심만 간결하게 적어보고자 한다.

 

 

만약 github이 아닌 카카오 로그인 붙이는 방법은 아래의 내용을 참고하자.

https://han-py.tistory.com/417

 

[React/Nodejs] 카카오 로그인 연결하기

카카오 로그인을 진행해 보자. 기본적인 작동 방식은 여기를 눌러서 확인하자. 기본 셋팅은 할수 있다 판단하고 글을 적어보겠다. 사실 쉽게 사용하기 위해 만들어진 라이브러리도 많다. 그러나

han-py.tistory.com

 

 

 

1. github OAuth 등록

당연한 말이지만 github에 oauth를 한다고 등록하는 과정이 우선 필요하다. https://github.com/settings/developers 로 접속을 해서 Apps를 하나 만들자.

 

위 사진에서 new OAuth App을 클릭한다. 

 

 

위와 같이 app 등록을 진행한다. 포함되어야할 내용을 아래와 같다. 

 

Application name : 자유롭게 이름을 넣어주면된다.

Homepage URL : 현재 localhost로 테스트 할꺼니 localhost로 적어주었다.

Authorization callback URL : ( 중요 ) callback URL을 적어주는 부분이다. github 셋팅을 한 이후에 아래 부분에서 조금 더 자세히 먹어보겠다.

 

 

 

우리가 application을 생성을 하면, 위와같이 clientIDclient secrets를 알 수 있다. 이부분을 저장해 두자.

 

 

2. github OAuth 전체 흐름

우리는 보통 아래의 버튼을 눌러서 내가 만든 페이지의 로그인을 진행한다.

 

버튼을 누르면, 아래의 페이지가 나온다.

 

 

위의 사진에서 로그인을 완료하면, 내가 적은 Authorization callback URL로 아래와 같이 code를 query로 담아서 redirect 해준다.

 

http://localhost:3000/api/auth/oauth/github/callback?code=1ad6213abf955df1b007

 

우리는 query에 포함된 code를 가지고 와서 다시 accesstoken을 github에 요청한다. 그리고 받은 access-token을 통해 우리는 상대방의 정보를 가지고 와서 로그인 처리를 할 수 있는 것이다.

 

 

3. code 구현

우선 버튼 클릭 시 github 로그인을 사용 할 수 있도록 만들어 보자.

 

위의 아이콘을 만드는 방법은 아래의 코드를 복사해서 사용하도록 하자. 간단히 버튼만 나오도록 css를 구성한것이다.

 

import styles from "@/styles/Login.module.css";
import { useRouter } from "next/navigation";

const Login = () => {
  const router = useRouter();
  const handleGithubLogin = () => {
    router.push(
      `${process.env.NEXT_PUBLIC_GITHUB_ORIGIN_URI}/login/oauth/authorize?client_id=${process.env.NEXT_PUBLIC_GITHUB_AUTHORIZE_CLIENT_ID}`
    );
  };
  return (
    <div className={styles.container}>
      <div onClick={handleGithubLogin} className={styles.githubone0}>
        <a className={styles.githubone1}>
          <div className={styles.githubone2}>
            <svg
              height="18"
              viewBox="0 0 16 16"
              width="32px"
              className={styles.githubone3}
            >
              <path
                fillRule="evenodd"
                d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38
      0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01
      1.08.58 1.23.82.72 1.21 1.87.87
      2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12
      0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08
      2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0
      .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"
              />
            </svg>
          </div>
          <div className={styles.githubone4}>Log in with GitHub</div>
        </a>
      </div>
    </div>
  );
};

export default Login;

 

위의 css는 아래와 같다.

 

.container {
  width: 100vw;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
}

.githubone0 {
  display: flex;
  flex-direction: column;
  width: 180px;
  margin-left: 20px;
}
.githubone1 {
  display: inline-flex;
  align-items: center;
  min-height: 30px;
  background-color: #24292e;
  font-family: "Roboto", sans-serif;
  font-size: 14px;
  color: white;
  border-radius: 10px;
  text-decoration: none;
  cursor: pointer;
}
.githubone2 {
  margin: 1px;
  padding-top: 5px;
  min-height: 30px;
}
.githubone3 {
  fill: white;
  margin-top: 3px;
}
.githubone4 {
  margin-left: 5px;
}

 

위의 코드에서 중요한 것은 사실 버튼이 아니라 아래의 이동 시키는 url이다.

 

`${process.env.NEXT_PUBLIC_GITHUB_ORIGIN_URI}/login/oauth/authorize?client_id=${process.env.NEXT_PUBLIC_GITHUB_AUTHORIZE_CLIENT_ID}`

 

env 파일로 빼 논부분을 풀면, 아래와 같이 사용하면된다. 만약 위에서 저장했던 clientID가 abcde라면 아래와 같이 적어두면 된다.

 

https://github.com/login/oauth/authorize?client_id=abcde

 

이게 끝이다. 그렇게 어려운 것은 없다. 위에서는 react(nextjs)를 활용하여 사용하였지만, 조금 더 직관적으로 html으로 표현하면 아래와 같다.

 

<a href="https://github.com/login/oauth/authorize?client_id=abcde">
 버튼
</a>

 

페이지만 이동시켜주면 아래와 같이 github이 알아서 로그인 처리를 해준다.

 

 

 

로그인이 완료가 되면 callback URL로 코드를 보내준다고 했다. 그러면 code 받는 로직을 참고용으로 간단히 적어보면, 아래와 같다. 사실 nextjs의 api 폴더에서 ssr로 만든 것이라 참고용으로 어려운 점은 없을 것이라 본다. 추후 nest 로 백엔드 만들예정이라, 만들면 추가를 하겠다.

 

import type { NextApiRequest, NextApiResponse } from "next";
import { getGithubAccessToken } from "@/lib/auth/github";

export default async function handle(
  req: NextApiRequest,
  res: NextApiResponse
) {
  if (req.method === "POST") res.end();
  if (req.method === "GET") {
    try {
      const { access_token } = await getGithubAccessToken(req, res);
      res.setHeader(
        "set-cookie",
        `token=${access_token}; path=/; samesite=strict; httponly; secure;`
      );
      return res.redirect(`/analyze`);
    } catch (error) {
      console.error("error: ", error);
      // 임시
      res.status(200).json(new Error());
    }
  }
}


async function getGithubAccessToken(req: NextApiRequest, res: NextApiResponse) {
  const { code } = req.query;
  try {
    const { data } = await axios.post(
      `${process.env.GITHUB_ORIGIN_URI}/login/oauth/access_token`,
      {
        client_id: process.env.GITHUB_AUTHORIZE_CLIENT_ID,
        client_secret: process.env.GITHUB_AUTHORIZE_CLIENT_SECRET,
        code: code,
      },
      {
        headers: { Accept: "application/json" },
      }
    );
    return data;
  } catch (err: any) {
    console.log(err.message);
    res.end();
  }
}

 

간단히 적으면 위와 같다. code를 받아서 다시 access_token을 요청을 하고, cookie로 담는 로직이다. cookie 담는 부분은 로그인 방식에 따라 정의하면 된다. 정리하면,

 

  1. query에서 code를 뽑는다.
  2. code와 client_id, client_secret을 담아서 호출하여 access-token을 받는다.

이 로직이 끝이다. access-token 호출 부분을 조금 더 설명하면 아래와 같다.

 

    const { data } = await axios.post(
      `https://github.com/login/oauth/access_token`,
      {
        client_id: process.env.GITHUB_AUTHORIZE_CLIENT_ID,
        client_secret: process.env.GITHUB_AUTHORIZE_CLIENT_SECRET,
        code: code,
      },
      {
        headers: { Accept: "application/json" },
      }
    );

 

client_id, client_secret은 app 등록 시 발급 받은 내용이고, code는 callback url로 받은 것이다. 추가적으로 headers에 application/json을 추가해 줘야 json으로 return 된다. 포함하지 않는다면, return이 string으로 온다.

 

 

4. 사용자 정보 불러오기

https://api.github.com/ 

위의 페이지에 접속해보면, 사용가능 한 API를 확인가능하다. 그리고 관련 자세한 정보에 대한 설명은 아래와 같다.

https://docs.github.com/ko/rest

 

GitHub REST API 설명서 - GitHub Docs

통합을 만들고, 데이터를 검색하고, 워크플로를 자동화하고, GitHub REST API를 사용하여 빌드합니다.

docs.github.com

 

로그인을 위한 user정보를 가지고 오려면, 아래의 내용을 참고하면 된다.

    const { data } = await axios.get(
      `https://api.github.com/user`,
      {
        headers: { 
          Accept: "application/json" 
          Authorization: 'Bearer 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',

        },
      }
    );

 

 

git의 repo 정보를 가지고 오려면 아래의 내용을 참고해서 만들면 된다.

    const { data } = await axios.get(
      `https://api.github.com/user/repo`,
      {
        headers: { 
          Accept: "application/json" 
          Authorization: 'Bearer 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',

        },
      }
    );

 

주의 할 점은 Bearer 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 부분에 Bearer 뒤에 access_token을 넣어주는 것인데, 너무 당연한 이야기 지만, Bearer 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을 그대로 못쓴다. 만료된 토큰이니, access_token을 발급하여 Bearer 발급한토큰 을 넣어줘야한다. 

 

 

이제 다양한 프로젝트에 github OAuth를 적용하고, 다양한 방법으로 github 데이터를 사용해 보자.

반응형

'Web > git' 카테고리의 다른 글

gitignore  (0) 2020.07.18
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함