
웹 서비스 개발 – OAuth 인증 – OAuth 클라이언트 구현
안녕하세요~ 개발자 여러분! 😄
이제 OAuth의 개념과 흐름, 서비스 제공자에 대해 충분히 이해하셨다면…
드디어 실전입니다!
이번 시간에는 OAuth 인증을 사용하는 클라이언트 애플리케이션을 직접 구현해보는 과정을 알려드릴게요.
“카카오 로그인 버튼 누르면 자동으로 로그인되던데… 그거 어떻게 만드는 거죠?”
👉 바로 오늘 알려드리는 내용이 그 비밀입니다!
1. OAuth 클라이언트란?
OAuth 클라이언트는
사용자 대신 인증 요청을 보내고, 토큰을 받아서 사용자 데이터를 호출하는 주체입니다.
쉽게 말해,
- 사용자와 OAuth 제공자(구글, 카카오 등) 사이에서
- **“인증 중계 역할”**을 하는 앱 or 웹 서비스예요.
2. 구현 흐름 한눈에 보기 🔁
[사용자]
↓ 로그인 클릭
[클라이언트 앱]
↓ 인가 요청 (Redirect)
[OAuth 제공자]
↓ 로그인 및 동의
↑ 인가 코드 반환 (리디렉션)
[클라이언트 앱]
↓ 인가 코드로 토큰 요청
[OAuth 제공자]
↑ Access Token 발급
[클라이언트 앱]
↓ 사용자 정보 요청 (토큰 포함)
[OAuth 제공자]
↑ 사용자 정보 응답
3. 실습 준비물 체크리스트 ✅
항목 | 준비 내용 |
---|---|
클라이언트 도메인 | 예: http://localhost:3000 |
OAuth 제공자 계정 | 예: 카카오 개발자 사이트 |
등록된 앱 | 클라이언트 ID, Secret, Redirect URI 등록 |
개발 환경 | PHP, Node.js, JavaScript 등 선택 가능 |
4. 클라이언트 구현 예제: PHP로 카카오 로그인 만들기
📌 Step 1. 인가 코드 요청 URL 생성
<?php
$client_id = 'YOUR_CLIENT_ID';
$redirect_uri = urlencode('http://localhost/callback.php');
$state = 'secureRandomState';
$auth_url = "https://kauth.kakao.com/oauth/authorize?response_type=code&client_id=$client_id&redirect_uri=$redirect_uri&state=$state";
?>
<a href="<?= $auth_url ?>">카카오 로그인</a>
사용자가 클릭하면, 카카오 인증창으로 리디렉션됩니다.
📌 Step 2. 인가 코드 수신 및 토큰 요청 (callback.php)
<?php
$code = $_GET['code'];
$client_id = 'YOUR_CLIENT_ID';
$client_secret = 'YOUR_CLIENT_SECRET';
$redirect_uri = 'http://localhost/callback.php';
$token_url = "https://kauth.kakao.com/oauth/token";
$data = [
'grant_type' => 'authorization_code',
'client_id' => $client_id,
'client_secret' => $client_secret,
'redirect_uri' => $redirect_uri,
'code' => $code
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $token_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
$response = curl_exec($ch);
curl_close($ch);
$token = json_decode($response, true);
$access_token = $token['access_token'];
📌 Step 3. Access Token으로 사용자 정보 요청
$user_url = "https://kapi.kakao.com/v2/user/me";
$headers = [
"Authorization: Bearer $access_token",
"Content-Type: application/x-www-form-urlencoded;charset=utf-8"
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $user_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$user_info = curl_exec($ch);
curl_close($ch);
$user = json_decode($user_info, true);
echo "안녕하세요, " . $user['properties']['nickname'] . "님!";
5. 프론트엔드 클라이언트 예제 (JavaScript SPA용)
Step 1. 리디렉션 URL로 인가 코드 받기
const params = new URLSearchParams(window.location.search);
const code = params.get('code');
// 받은 code를 백엔드로 전송하여 토큰 요청 처리
fetch('/auth/kakao/callback?code=' + code)
.then(res => res.json())
.then(data => {
console.log('사용자 정보:', data);
});
백엔드에서 token을 받고 사용자 정보까지 조회해서 프론트로 전달해주는 방식이 가장 보안에 좋아요!
6. 리프레시 토큰으로 토큰 재발급하기 (선택)
$refresh_token = $token['refresh_token'];
$refresh_data = [
'grant_type' => 'refresh_token',
'client_id' => $client_id,
'refresh_token' => $refresh_token
];
// cURL 요청 생략 – 위와 유사하게 전송
7. 다른 언어에서도 가능해요! (Node.js, Python 등)
Node.js 예시 (Express + Axios)
const axios = require('axios');
app.get('/auth/kakao/callback', async (req, res) => {
const { code } = req.query;
const tokenRes = await axios.post('https://kauth.kakao.com/oauth/token', {
grant_type: 'authorization_code',
client_id: YOUR_CLIENT_ID,
redirect_uri: YOUR_REDIRECT_URI,
code
}, {
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
});
const accessToken = tokenRes.data.access_token;
const userRes = await axios.get('https://kapi.kakao.com/v2/user/me', {
headers: { Authorization: `Bearer ${accessToken}` }
});
res.json(userRes.data);
});
8. 주의할 점 정리 ✅
항목 | 주의 사항 |
---|---|
Redirect URI 등록 필수 | 인가 서버에 등록된 URI와 정확히 일치해야 합니다 |
Access Token 노출 주의 | JS로 직접 노출하지 말고 서버에서 처리 권장 |
HTTPS 통신 사용 | 인증 및 토큰 교환 시 반드시 HTTPS 사용 |
상태(state) 값 검증 | CSRF 공격 방지를 위해 state를 확인하세요 |
토큰 저장 방식 | 브라우저엔 HttpOnly 쿠키를 권장합니다 |
마무리하며 🎉
오늘은 실제로 OAuth 클라이언트를 구현하는 전 과정을 함께 살펴봤어요!
- 인가 코드 요청
- Access Token 요청
- 사용자 정보 요청
- 토큰 재발급
이제 여러분은 카카오, 네이버, 구글 같은 OAuth 서비스와
자신의 웹사이트를 안전하게 연결할 수 있는 준비가 되셨습니다! 💪
다음 편에서는 실전 프로젝트에서 OAuth 클라이언트를 어떻게 구조화하고,
다양한 API와 함께 쓰는지까지 심화 내용을 다뤄볼게요!
궁금하신 점은 언제든지 댓글로 남겨주세요.
감사합니다! 🙏