12월 5일 (일) OAuth 2.0

남이섬·2021년 12월 5일
0
post-custom-banner

OAuth 생성 과정 (서버)

1. GitHub에 내 앱 등록

ex

github 앱등록

Authorization callback URL은 무엇인가요?

OAuth 메커니즘이 인증 과정이 끝난 후 리디렉션을 통해 다시 내 앱으로 이동하는 원리이므로, 내 앱으로 돌아가기 위한 Authorization callback URL이 필요합니다.

app -> OAuth 인증 페이지 -> 다시 app 순이므로,
인증 페이지에서 다시 app으로 돌아가야 하는 url이 바로
Authorization callback URL 이다

2. 환경 설정

env 파일안에 clientID와 clientSecret 정보를 담는다

3. 서버 분석 및 서버 실행

express를 이용해 만든 간단한 웹 서버를 만든다

const express = require('express');
const app = express();
const cors = require('cors');
const PORT = process.env.PORT || 8080;

app.use(express.json());

app.use(
  cors({ origin: true })
);

app.listen(PORT, () => {
  console.log(`listening on port ${PORT}`);
});

module.exports = app;

endpoint와 메소드에 따른 분기 설정

const handleCallback = require('./controller/callback')
const handleImages = require('./controller/images')

app.post('/callback', handleCallback);

app.get('/images', handleImages)

Access token을 발급받는 과정은 서버에서 이루어지는 것이 더욱 안전하다, 그래서

  • 클라이언트에서 받아온 Authorization code를 서버의 /callback 엔드포인트로 전달한 다음
  • 서버에서 github App에게 Access token 발급을 요청한다

/callback: 인증 정보를 바탕으로 Access token을 받아올 수 있도록 도와주는 라우터다

/images: 받아온 Access token을 확인한 후, local에 저장된 resource images를 클라이언트로 보내주는 라우터다

OAuth 생성 과정 (클라이언트)

4. Authorization code 받아오기 (Login Component)

가장 먼저 해야 할 일은 Github App에 요청을 보내 Authorization code를 받아온다

5. Access token 받아 오기 (App Component)

Authorization code를 받아왔다면 해당 코드를 server(server > index.js)에 전달해 Access token을 받아올 수 있다

받아온 Access token은 App 컴포넌트의 state에 저장한 후, Mypage 컴포넌트에서 props로 내려받아 활용한다

6. 리소스 서버에 리소스 요청 (Mypage Component)

받아온 Access Token으로 client > src > components > Mypage.js 에서 리소스에 대한 API 요청을 할 수 있다

Access Token을 전달하는 방식은 앞서 토큰에서 배웠던 Bearer Token 을 headers에 담아 주어 전달할 수 있다

Mypage에서 받아와야 할 리소스는 2가지다

  • 먼저 Github API 요청에 Access token을 함께 보내어 유저 정보를 받아온다
  • local server에 저장된 이미지들을 받아온다
    완성된 마이페이지 화면에는 Github user 정보와 Resource 서버에 있는 이미지들이 담겨야 한다

OAuth 생성 과정 (서버 코드)

index.js

  • express 사용으로 서버 구성
  • 엔드포인트로 분기
const express = require('express');
const app = express();
const cors = require('cors');
const PORT = process.env.PORT || 8080;

const handleCallback = require('./controller/callback')
const handleImages = require('./controller/images')

app.use(express.json());

app.use(
  cors({ origin: true })
);

app.post('/callback', handleCallback);

app.get('/images', handleImages)

app.listen(PORT, () => {
  console.log(`listening on port ${PORT}`);
});

module.exports = app;

callback.js

인증 정보를 바탕으로 Access token을 받아올 수 있도록 도와주는 라우터

1. authorization code를 이용하여 Access token을 받아 온다 (axios 이용)

axios를 이용하여 authorization code를 이용해 access token을 발급받기

GitHub 앱 사용자 식별 및 권한 부여

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

작성 코드

require('dotenv').config();

const clientID = process.env.GITHUB_CLIENT_ID;
const clientSecret = process.env.GITHUB_CLIENT_SECRET;
const axios = require('axios');

module.exports = (req, res) => {
axios.post('https://github.com/login/oauth/access_token', { client_id: clientID, client_secret: clientSecret, code: req.body.authorizationCode })
    .then(tokenData => {
      res.status(200).send({ accessToken: tokenData.data.access_token })
    })
}

images.js

받아온 Access token을 확인한 후, local에 저장된 resource images를 클라이언트로 보내주는 라우터

Mypage로부터 access token을 제대로 받아온 것이 맞다면, resource server의 images를 클라이언트로 보내준다

작성 코드

const images = require('../resources/resources');

module.exports = (req, res) => {

  const authorization = req.headers.authorization

  if (!authorization) {
    res.status(403).send({ message: 'no permission to access resources' })
  } else {
    res.status(200).send({ authorization, images })
  }
}

OAuth 생성 과정 (클라이언트 코드)

Login.js (Authorization code 받아오기)

GitHub로부터 사용자 인증을 위해 GitHub로 이동해야 한다

1. Request a user's GitHub identity
Direct the user to the following URL in their browser:

GET https://github.com/login/oauth/authorize

GitHub 앱 사용자 식별 및 인증

작성 코드

import React, { Component } from 'react';

class Login extends Component {
  constructor(props) {
    super(props)

    this.socialLoginHandler = this.socialLoginHandler.bind(this)

    this.GITHUB_LOGIN_URL = 'https://github.com/login/oauth/authorize?client_id=115e806b0be55f28ab98'
  }

  socialLoginHandler() {
window.location.assign(this.GITHUB_LOGIN_URL)
  }

  render() {
    return (
      <div className='loginContainer'>
        OAuth 2.0으로 소셜 로그인을 구현해보세요.
        <img id="logo" alt="logo" src="https://image.flaticon.com/icons/png/512/25/25231.png" />
        <button
          onClick={this.socialLoginHandler}
          className='socialloginBtn'

          Github으로 로그인
        </button>
      </div>
    );
  }
}
export default Login;

App.js

Authorization code를 받아왔다면 해당 코드를 server(server > index.js)에 전달해,
Access token을 받아올 수 있다

받아온Access token은 App 컴포넌트의 state에 저장한 후, Mypage 컴포넌트에서 props로 내려받아 활용

  • 받아온 authorization code로 다시 OAuth App에 요청해서 access token을 받을 수 있다
  • access token은 보안 유지가 필요하기 때문에 클라이언트에서 직접 OAuth App에 요청을 하는 방법은 보안에 취약할 수 있다
  • authorization code를 서버로 보내주고, 서버에서 access token 요청을 하는 것이 적절하다
    즉, axios를 사용하여 post 요청으로 http://localhost:8080/callback 서버로 authorizationCode와 함께 보내어 accessToken을 받아 온다
    작성 코드
this.state = {
      isLogin: false,
      accessToken: '',
}

async getAccessToken(authorizationCode) {

const getToken = await axios.post('http://localhost:8080/callback', { authorizationCode })

    this.setState({
      isLogin: true,
      accessToken: getToken.data.accessToken
    })

Mypage.js

받아온 Access Token으로 client > src > components > Mypage.js 에서 리소스에 대한 API 요청을 할 수 있다

Access Token을 전달하는 방식은 앞서 토큰에서 배웠던 Bearer Token 을 headers에 담아 주어 전달할 수 있다

Mypage에서 받아와야 할 리소스는 2가지입니다.

  1. 먼저 Github API 요청에 Access token을 함께 보내어 유저 정보를 받아온다

  2. local server에 저장된 이미지들을 받아온다

profile
즐겁게 살자
post-custom-banner

0개의 댓글