본문 바로가기
TECH

OAuth / CI와 DI / Auth Bearer ✍🏻

by Stella-Park 2025. 6. 24.
728x90

OAuth (OpenAuthorization)

권한 위임을 위한 표준 프로토콜이다. 사용자가 비밀번호를 제3자 앱에 제공하지 않고 서비스 접근 권한을 위임할 수 있게 한다.

"나의 자격증명은 그대로 두고, 일부 권한만 제3자에게 위임하는 것"

 

 

OAuth 2.0 핵심 구조

구성 요소   설명 역할
Resource Owner 인증받을 사용자 리소스의 실제 소유자 (ex: 사용자)
Client OAuth를 사용하는 앱 리소스를 사용하려는 앱 (ex: 카카오톡에 연결된 외부 앱)
Authorization Server 로그인 인증 및 토큰 발급 사용자 인증 및 토큰 발급 처리 (ex: Google)
Resource Server 보호된 리소스를 제공하는 API 서버 실제 API 자원이 있는 곳 (ex: Google Calendar API)

 

든든 앱에서 구글 로그인으로 회원가입 및 로그인을 한다면, OAuth에서 Resource ServerGoogle의 사용자 정보 API를 가리킨다.

 

 

요약 단계

  1. 사용자가 로그인 요청 → 인증서버로 리디렉션
  2. 사용자 로그인 & 동의 → Authorization Code 발급
  3. 클라이언트가 서버로 Code 전달 → Access Token 발급
  4. Access Token으로 API 요청

 

흐름 그림

[Client] ──▶ [Authorization Server]
    1. Redirect with client_id, redirect_uri, scope


[User] ◀─ 로그인/동의 화면


[Authorization Server] ──▶ [Client]
    2. Redirect with code


[Client] ──▶ [Authorization Server]
    3. POST /token with code, client_secret


[Authorization Server] ──▶ [Client]
    4. Response with access_token


[Client] ──▶ [Resource Server]
    5. API call with Authorization: Bearer <access_token>

 

node.js와 express로 만든 예제코드

 

// 로그인 요청
import express from 'express';

const router = express.Router();
const clientID = process.env.GOOGLE_CLIENT_ID;
const redirectURI = 'http://localhost:3000/oauth2callback';
const scope = encodeURIComponent('profile email');

router.get('/login', (req, res) => {
  const authURL = `https://accounts.google.com/o/oauth2/v2/auth?` +
    `client_id=${clientID}&redirect_uri=${redirectURI}&response_type=code&scope=${scope}`;

  res.redirect(authURL);
});

export default router;

 

// 콜백 핸들러
import express from 'express';
import axios from 'axios';


const router = express.Router();
const clientID = process.env.GOOGLE_CLIENT_ID;
const clientSecret = process.env.GOOGLE_CLIENT_SECRET;
const redirectURI = 'http://localhost:3000/oauth2callback';


router.get('/oauth2callback', async (req, res) => {
  const code = req.query.code as string;

  // Step 3: Access Token 요청
  const response = await axios.post(
    'https://oauth2.googleapis.com/token',
    {
      code,
      client_id: clientID,
      client_secret: clientSecret,
      redirect_uri: redirectURI,
      grant_type: 'authorization_code',
    },
    {
      headers: {
        'Content-Type': 'application/json',
      },
    }
  );

  const { access_token, id_token } = response.data;
  
  // Step 4: User Info 요청
  const userInfo = await axios.get('https://www.googleapis.com/oauth2/v2/userinfo', {
    headers: {
      Authorization: `Bearer ${access_token}`,
    },
  });

  res.json(userInfo.data);
});


export default router;

 

이 외 개념들

Scope

  • 사용자가 허용할 권한 범위 (예: email, calendar.readonly)
  • 적절한 scope를 지정하면 최소 권한 원칙을 지킬 수 있음

 PKCE (Proof Key for Code Exchange)

  • 모바일 앱/SPA 같은 public client를 위한 보안 강화 기법
  • 코드 탈취 방지

 

728x90

 

CI와 DI

본인인증 시스템에 사용되고, 휴대폰 본인인증 과정에서 많이 사용된다.

 

CI (Connecting Information): 개인 식별

  • CI는 개인 식별자로, 다양한 서비스 간 동일인을 식별하기 위한 고유값이다.
  • 이름, 주민번호, 휴대폰번호 등으로 인증받은 결과로 1인당 1개씩 고정된 값이 생성된다.
  • 서비스 간 연동 시 같은 사람인지를 판별하는 데 사용된다.

 

특징

  • 암호화된 해시값 (개인정보 유출 방지를 위해)
  • 동일인이 여러 서비스에 가입했을 때, 서로 CI 값이 같음
  • 사용자의 실명/주민번호 없이도 동일성 확인 가능

 

A 서비스와 B 서비스에 가입한 이용자가 있을 때,

  • 두 서비스 모두 같은 휴대폰 인증을 통해 CI 값을 받으면
  • 운영자는 두 계정이 동일인이라는 것만 파악 가능 (실명은 모름)

 

 

DI (Duplication Information): 중복 방지

  • DI는 중복 가입을 방지하기 위한 식별자이다.
  • 인증을 요청한 각 서비스마다 고유한 값으로 생성된다.
  • 특정 서비스 내에서 1인이 여러 번 가입하는 것을 방지할 수 있도록 설계되었다.

 특징

  • 동일 사용자가 여러 서비스에 가입해도 DI 값은 서로 다름
  • 하지만 한 서비스 안에서 같은 사람이 중복 인증하면 DI는 동일함
  • CI가 "사람 중심 식별자"라면, DI는 “서비스 중심 식별자”

예를 들어, 어떤 쇼핑몰에서 휴대폰 본인인증을 두 번 시도해도 다른 서비스에 가입하면 DI는 다르다. → 서비스 간 추적 불가

 

항목 CI (Connecting Information) DI (Duplication Information)
용도 동일인 여부 확인 중복 가입 방지
값 생성 모든 서비스에서 동일 서비스마다 다름
사용자 추적 가능 (단, 암호화됨) 불가
개인정보 포함 여부 아님 (암호화된 값) 아님 (암호화된 값)

 

Auth Bearer (Bearer Token Authentication): 세션 인증

Bearer 토큰 인증은 API 요청 시 Authorization 헤더에 토큰을 포함하여 사용자 인증을 하는 방식이다. 

Authorization: Bearer <token>

 

“이 토큰을 가진 자가 권한이 있다”는 의미이며, 토큰 자체가 신뢰 기반 자격 증명을 의미한다.

 

 

예를 들면

  1. 클라이언트가 OAuth 로그인 → Access Token 받음
  2. 이후 모든 API 요청 헤더에
    Authorization: Bearer eyJhbGciOiJIUzI1NiIsIn...
  3. 서버는 토큰 유효성 검증 요청 처리

 

개발할 때 꼭 필요한 "인증"에 대해서 공부해보았다!

728x90