Google OAuth 2.0을 PHP로 연결하는 샘플 예제

많은 분들이 어려워하는 Google OAuth 2.0 PHP 연동 예제를 만들어 드리니 참고해서 작성해보세요 ^^

🔑 주요 기능

  1. index.php - Google 로그인 버튼이 있는 메인 페이지
  2. callback.php - Google에서 돌아오는 콜백 처리
  3. dashboard.php - 로그인 후 사용자 정보 표시
  4. logout.php - 로그아웃 및 토큰 취소
  5. GoogleOAuth.php - 재사용 가능한 클래스 버전

📝 설정 방법

1. Google Cloud Console 설정

  1. Google Cloud Console 접속
  2. 새 프로젝트 생성
  3. "API 및 서비스" → "사용자 인증 정보" 이동
  4. "사용자 인증 정보 만들기" → "OAuth 클라이언트 ID" 선택
  5. 애플리케이션 유형: 웹 애플리케이션
  6. 승인된 리디렉션 URI 추가: http://localhost/callback.php
  7. Client ID와 Client Secret 복사

2. PHP 코드 수정

 
 
php
const CLIENT_ID = '여기에_클라이언트_ID_입력';
const CLIENT_SECRET = '여기에_클라이언트_시크릿_입력';

3. 필요한 PHP 확장

  • curl (대부분 기본 설치됨)
  • json

🚀 실행 방법

  1. 파일들을 웹 서버 루트에 배치
  2. http://localhost/index.php 접속
  3. "Google로 로그인" 버튼 클릭
  4. Google 계정 선택 및 권한 승인

 

 

예제코드

<?php
/**
 * Google OAuth 2.0 PHP 연동 예제
 * 
 * 사전 준비:
 * 1. Google Cloud Console에서 프로젝트 생성
 * 2. OAuth 2.0 클라이언트 ID 생성 (웹 애플리케이션)
 * 3. 승인된 리디렉션 URI 추가: http://localhost/callback.php
 */

// config.php - 설정 파일
class GoogleOAuthConfig {
    const CLIENT_ID = 'YOUR_CLIENT_ID.apps.googleusercontent.com';
    const CLIENT_SECRET = 'YOUR_CLIENT_SECRET';
    const REDIRECT_URI = 'http://localhost/callback.php';
    const SCOPE = 'https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile';
}

// ============================================
// index.php - 로그인 페이지
// ============================================
session_start();

function getGoogleLoginUrl() {
    $params = [
        'client_id' => GoogleOAuthConfig::CLIENT_ID,
        'redirect_uri' => GoogleOAuthConfig::REDIRECT_URI,
        'response_type' => 'code',
        'scope' => GoogleOAuthConfig::SCOPE,
        'access_type' => 'offline',
        'prompt' => 'consent'
    ];
    
    return 'https://accounts.google.com/o/oauth2/v2/auth?' . http_build_query($params);
}

?>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Google OAuth 로그인</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            background: #f5f5f5;
        }
        .login-container {
            background: white;
            padding: 40px;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
            text-align: center;
        }
        .google-btn {
            display: inline-flex;
            align-items: center;
            background: #4285f4;
            color: white;
            padding: 12px 24px;
            border: none;
            border-radius: 4px;
            text-decoration: none;
            font-size: 16px;
            cursor: pointer;
            transition: background 0.3s;
        }
        .google-btn:hover {
            background: #357ae8;
        }
        .google-icon {
            background: white;
            padding: 8px;
            border-radius: 2px;
            margin-right: 12px;
        }
    </style>
</head>
<body>
    <div class="login-container">
        <h1>Google 로그인</h1>
        <p>Google 계정으로 로그인하세요</p>
        <a href="<?php echo getGoogleLoginUrl(); ?>" class="google-btn">
            <span class="google-icon">G</span>
            Google로 로그인
        </a>
    </div>
</body>
</html>

<?php
// ============================================
// callback.php - 콜백 처리 페이지
// ============================================
session_start();

if (isset($_GET['code'])) {
    $code = $_GET['code'];
    
    // 액세스 토큰 요청
    $tokenUrl = 'https://oauth2.googleapis.com/token';
    $params = [
        'code' => $code,
        'client_id' => GoogleOAuthConfig::CLIENT_ID,
        'client_secret' => GoogleOAuthConfig::CLIENT_SECRET,
        'redirect_uri' => GoogleOAuthConfig::REDIRECT_URI,
        'grant_type' => 'authorization_code'
    ];
    
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $tokenUrl);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    
    if ($httpCode == 200) {
        $tokenData = json_decode($response, true);
        $accessToken = $tokenData['access_token'];
        
        // 사용자 정보 요청
        $userInfoUrl = 'https://www.googleapis.com/oauth2/v2/userinfo';
        
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $userInfoUrl);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Authorization: Bearer ' . $accessToken
        ]);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        
        $userInfoResponse = curl_exec($ch);
        curl_close($ch);
        
        $userInfo = json_decode($userInfoResponse, true);
        
        // 세션에 사용자 정보 저장
        $_SESSION['user'] = $userInfo;
        $_SESSION['access_token'] = $accessToken;
        
        // 대시보드로 리디렉션
        header('Location: dashboard.php');
        exit;
    } else {
        echo "토큰 요청 실패: " . $response;
    }
} else if (isset($_GET['error'])) {
    echo "인증 오류: " . $_GET['error'];
} else {
    echo "잘못된 요청입니다.";
}

// ============================================
// dashboard.php - 로그인 후 페이지
// ============================================
session_start();

if (!isset($_SESSION['user'])) {
    header('Location: index.php');
    exit;
}

$user = $_SESSION['user'];
?>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>대시보드</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            padding: 20px;
            background: #f5f5f5;
        }
        .dashboard {
            max-width: 600px;
            margin: 0 auto;
            background: white;
            padding: 30px;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }
        .profile-img {
            width: 100px;
            height: 100px;
            border-radius: 50%;
            margin-bottom: 20px;
        }
        .info-row {
            margin: 10px 0;
            padding: 10px;
            background: #f9f9f9;
            border-radius: 4px;
        }
        .logout-btn {
            background: #dc3545;
            color: white;
            padding: 10px 20px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            margin-top: 20px;
        }
        .logout-btn:hover {
            background: #c82333;
        }
    </style>
</head>
<body>
    <div class="dashboard">
        <h1>환영합니다!</h1>
        
        <?php if (isset($user['picture'])): ?>
            <img src="<?php echo htmlspecialchars($user['picture']); ?>" 
                 alt="프로필 이미지" class="profile-img">
        <?php endif; ?>
        
        <div class="info-row">
            <strong>이름:</strong> <?php echo htmlspecialchars($user['name']); ?>
        </div>
        
        <div class="info-row">
            <strong>이메일:</strong> <?php echo htmlspecialchars($user['email']); ?>
        </div>
        
        <div class="info-row">
            <strong>Google ID:</strong> <?php echo htmlspecialchars($user['id']); ?>
        </div>
        
        <?php if (isset($user['verified_email'])): ?>
        <div class="info-row">
            <strong>이메일 인증:</strong> 
            <?php echo $user['verified_email'] ? '완료' : '미완료'; ?>
        </div>
        <?php endif; ?>
        
        <form action="logout.php" method="post">
            <button type="submit" class="logout-btn">로그아웃</button>
        </form>
    </div>
</body>
</html>

<?php
// ============================================
// logout.php - 로그아웃 처리
// ============================================
session_start();

// Google 액세스 토큰 취소 (선택사항)
if (isset($_SESSION['access_token'])) {
    $accessToken = $_SESSION['access_token'];
    $revokeUrl = 'https://oauth2.googleapis.com/revoke?token=' . $accessToken;
    
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $revokeUrl);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_exec($ch);
    curl_close($ch);
}

// 세션 삭제
session_destroy();

// 로그인 페이지로 리디렉션
header('Location: index.php');
exit;
?>

<?php
// ============================================
// GoogleOAuth.php - 클래스 버전 (선택사항)
// ============================================

class GoogleOAuth {
    private $clientId;
    private $clientSecret;
    private $redirectUri;
    private $scope;
    
    public function __construct($clientId, $clientSecret, $redirectUri, $scope) {
        $this->clientId = $clientId;
        $this->clientSecret = $clientSecret;
        $this->redirectUri = $redirectUri;
        $this->scope = $scope;
    }
    
    public function getAuthUrl() {
        $params = [
            'client_id' => $this->clientId,
            'redirect_uri' => $this->redirectUri,
            'response_type' => 'code',
            'scope' => $this->scope,
            'access_type' => 'offline',
            'prompt' => 'consent'
        ];
        
        return 'https://accounts.google.com/o/oauth2/v2/auth?' . http_build_query($params);
    }
    
    public function getAccessToken($code) {
        $tokenUrl = 'https://oauth2.googleapis.com/token';
        $params = [
            'code' => $code,
            'client_id' => $this->clientId,
            'client_secret' => $this->clientSecret,
            'redirect_uri' => $this->redirectUri,
            'grant_type' => 'authorization_code'
        ];
        
        return $this->makeRequest($tokenUrl, $params, true);
    }
    
    public function getUserInfo($accessToken) {
        $userInfoUrl = 'https://www.googleapis.com/oauth2/v2/userinfo';
        $headers = ['Authorization: Bearer ' . $accessToken];
        
        return $this->makeRequest($userInfoUrl, null, false, $headers);
    }
    
    public function revokeToken($accessToken) {
        $revokeUrl = 'https://oauth2.googleapis.com/revoke?token=' . $accessToken;
        return $this->makeRequest($revokeUrl, [], true);
    }
    
    private function makeRequest($url, $params = null, $isPost = false, $headers = []) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        
        if ($isPost) {
            curl_setopt($ch, CURLOPT_POST, true);
            if ($params) {
                curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
            }
        }
        
        if (!empty($headers)) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        }
        
        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        
        if ($httpCode == 200) {
            return json_decode($response, true);
        }
        
        return false;
    }
}

// 사용 예제
/*
$oauth = new GoogleOAuth(
    GoogleOAuthConfig::CLIENT_ID,
    GoogleOAuthConfig::CLIENT_SECRET,
    GoogleOAuthConfig::REDIRECT_URI,
    GoogleOAuthConfig::SCOPE
);

// 로그인 URL 생성
$loginUrl = $oauth->getAuthUrl();

// 토큰 받기
$tokenData = $oauth->getAccessToken($_GET['code']);

// 사용자 정보 받기
$userInfo = $oauth->getUserInfo($tokenData['access_token']);
*/
?>
TAGS.

Comments