GitHub OAuth를 활용한 인증 구현

henry·2025년 1월 21일

GitHub OAuth란?
GitHub OAuth는 OAuth 2.0 프로토콜을 기반으로 사용자를 인증하고
GitHub API에 접근할 수 있도록 Access Token발급받는 방식


사용법


🚩 Step 1

GitHub OAuth 앱 등록


OAuth 앱 등록

  • OAuth Apps에서 New OAuth App 클릭 후 정보 입력:

  • Application name

    • 애플리케이션 이름 입력란
  • Homepage URL

    • 서비스 홈페이지 URL 입력란
  • Authorization callback URL


Client ID 및 Secret 발급

  • 등록 완료 시 GitHub이 제공하는 Client ID와 Client Secret을 애플리케이션에서 사용.



🚩 Step 2

서버 초기 설정


환경 변수 설정

  • .env 파일에 GitHub OAuth 관련 정보를 저장
    GITHUB_CLIENT_ID=your_github_client_id
    GITHUB_CLIENT_SECRET=your_github_client_secret
    GITHUB_CALLBACK_URL=http://localhost:5000/auth/github/callback
    JWT_SECRET_KEY=your_jwt_secret_key

Express 서버 구성

  • 서버에서 GitHub OAuth 요청과 콜백 처리를 담당.


📌Step 3

GitHub OAuth 요청 처리


GitHub 로그인 리다이렉트

  • 사용자가 GitHub 로그인 페이지로 이동하도록 설정.
  • 서버에서 /auth/github 경로를 통해 요청을 처리.
  • 리다이렉트 URL 예제
const redirectToGitHub = (req: Request, res: Response) => {
  const redirectURI = `https://github.com/login/oauth/authorize?client_id=${GITHUB_CLIENT_ID}
						&redirect_uri=${GITHUB_CALLBACK_URL}&scope=user:email`;
  res.redirect(redirectURI);
};

GitHub 로그인 콜백

  • GitHub 로그인 완료 후, GitHub는 Authorization Code서버로 전달.

  • 서버는 이 코드를 사용해 Access Token을 요청.

  • Access Token 요청 로직

    export const handleGitHubCallback = async (
      req: Request,
      res: Response
    ): Promise<void> => {
      const code = req.query.code as string;
    
      if (!code) {
        res.status(400).json({ error: 'Authorization code is missing' });
        return;
      }
    
      try {
        console.log('Access Token 요청');
        //
        const tokenResponse = await axios.post(
          'https://github.com/login/oauth/access_token',
          {
            client_id: GITHUB_CLIENT_ID,
            client_secret: GITHUB_CLIENT_SECRET,
            code,
          },
          { headers: { Accept: 'application/json' } }
        );
    
        const accessToken = tokenResponse.data.access_token;
    
        if (!accessToken) {
          throw new Error('Failed to obtain access token');
        }
    
        if (!userInfo.email) {
          throw new Error('Primary email not found');
        }
    
        //JWT 생성
        const token = jwt.sign(userInfo, JWT_SECRET_KEY!, { expiresIn: '1h' });
    
        //성공적으로 로그인 처리
        res.status(200).json({
          message: 'GitHub 로그인 성공',
          token,
          user: userInfo,
        });
      } catch (error) {
        console.error('GitHub OAuth Error:', error);
        res.status(500).json({ error: 'GitHub OAuth Failed' });
      }
    };
    

사용자 정보 요청

  • Access Token을 사용해 GitHub API를 호출하고 사용자 정보를 가져옴.
  • GitHub 사용자 정보 요청
    const userResponse = await axios.get("https://api.github.com/user", {
      headers: { Authorization: `Bearer ${accessToken}` },
    });
    const userEmailResponse = await axios.get("https://api.github.com/user/emails", {
      headers: { Authorization: `Bearer ${accessToken}` },
    });
    const userInfo = {
      id: userResponse.data.id,
      username: userResponse.data.login,
      email: userEmailResponse.data.find((email: any) => email.primary)?.email,
    };

JWT 생성 및 반환

  • 사용자 정보를 기반으로 JWT를 생성하여 클라이언트에 전달.
  • JWT 생성 로직
    const token = jwt.sign(userInfo, JWT_SECRET!, { expiresIn: "1h" });
    res.status(200).json({
      message: "GitHub 로그인 성공",
      token,
      user: userInfo,
    });


테스트


1. 로그인 요청

app.ts

app.use('/auth', authRoutes);

authRoutes.ts

router.get('/github', redirectToGitHub);

Request

GET
http://localhost:5000/auth/github

2. 응답

로그인 성공 JSON 데이터

{
  "message":"GitHub 로그인 성공",
  "token":"eyJhbGciOiJIUzI1Ni.......",
  "user":{
    "id":75677589,"username":"vedivero","email":"vedivero73@gmail.com"
  }
}

0개의 댓글