0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

WebアプリとGoogleログイン機能

Last updated at Posted at 2024-12-23

①まずは下記のURLにログインした状態で「APIとサービス」に移動※プロジェクトを作成する
https://console.cloud.google.com/
手順1.png

②「認証情報」をクリック
手順2.png

③「認証情報を作成」の「OAuthクライアントID」を選択
手順3.png

④「承認済みの JavaScript 生成元」(使用するURLのドメイン)を設定

⑤「承認済みのリダイレクト URIを設定」(ログイン認証するURL)

Googleログインを実装するページ[index.php]
Googleにトークンを送信する処理[session_handler.php]
Googleの認証OKの場合に移動するページ[dashboard.php]

Googleログインの流れ図.png

index.php

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Googleログイン</title>
    <!-- Google Identity Servicesライブラリ -->
    <script src="https://accounts.google.com/gsi/client" async defer></script>
    <script src="https://cdn.jsdelivr.net/npm/jwt-decode/build/jwt-decode.min.js"></script>
</head>
<body>
    <!-- Googleログインボタン -->
    <div id="g_id_onload"
         data-client_id="GoogleのAPIとサービスで取得したID"
         data-callback="handleCredentialResponse"
         data-auto_prompt="false">
    </div>
    <div class="g_id_signin" data-type="standard"></div>

    <h1>ユーザー情報</h1>
    <div id="user-info"></div>

<script>
async function handleCredentialResponse(response) {
    try {
        // セッション保存用のエンドポイントにPOSTリクエストを送信
        const serverResponse = await fetch('./session_handler.php', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({ credential: response.credential })
        });

        if (!serverResponse.ok) {
            throw new Error(`HTTP error! status: ${serverResponse.status}`);
        }

        const responseData = await serverResponse.json();
        if (responseData.status === 'success') {
            alert('Authentication successful! Redirecting to dashboard...');
            window.location.href = './dashboard.php';
        } else {
            throw new Error(responseData.message || 'Unknown error occurred');
        }
    } catch (error) {
        console.error('Unexpected error in handleCredentialResponse:', error);
        alert('An unexpected error occurred. Please try again later.');
    }
}

</script>
</body>
</html>

session_handler.php

<?php
session_start();

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $data = json_decode(file_get_contents('php://input'), true);

    if (isset($data['credential'])) {
        $credential = $data['credential'];

        // Googleトークンを検証してユーザー情報を取得(GoogleのAPIを利用する例)
        $userInfo = verifyGoogleToken($credential);

        if ($userInfo) {
            // セッションに保存
            $_SESSION['user'] = $userInfo;

            // 成功レスポンスを返す
            echo json_encode(['status' => 'success']);
        } else {
            http_response_code(400);
            echo json_encode(['status' => 'error', 'message' => 'Invalid Google credential']);
        }
    } else {
        http_response_code(400);
        echo json_encode(['status' => 'error', 'message' => 'Credential not provided']);
    }
}

function verifyGoogleToken($credential) {
    // トークンをデコードして検証する(GoogleのAPIを使う方法の一例)
    $url = 'https://oauth2.googleapis.com/tokeninfo?id_token=' . $credential;

    $response = file_get_contents($url);
    $userInfo = json_decode($response, true);

    if (isset($userInfo['sub'])) {
        return [
            'id' => $userInfo['sub'],
            'name' => $userInfo['name'],
            'email' => $userInfo['email'],
            'picture' => $userInfo['picture']
        ];
    }

    return null;
}
?>

dashboard.php

<?php
session_start();

if (!isset($_SESSION['user'])) {
    // 未ログインの場合はログインページにリダイレクト
    header('Location: index.php');
    exit;
}

$user = $_SESSION['user'];

?>

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Dashboard</title>
<style>
* {
  margin: 0;
  padding: 0;
}

.app {
  width: 100vw;
  height: 100vh;
  display: flex;
  flex-direction: column;
}

.header {
  height: auto;
  background-color: lightcyan;
  box-sizing: border-box;
  border: 8px solid blue;
}

.main {
  display: flex;
  flex-direction: row;
  flex-grow: 1;
}

.sideBar {
  width: auto;
  background-color: moccasin;
  box-sizing: border-box;
  border: 8px solid chocolate;
}

.content {
  display: flex;
  flex-direction: column;
  flex-grow: 1;
}

.flex-content {
  flex-grow: 1;
  background-color: palegoldenrod;
  box-sizing: border-box;
  display: flex;
  flex-direction: row;
  border: 8px solid green;
}

.fixed-content {
  background-color: thistle;
  box-sizing: border-box;
  border: 8px solid darkmagenta;
}

.Edit_Area textarea,
.Edit_Area a {
    width: 50%;
    box-sizing: border-box; /* パディングやボーダーを含めた幅計算 */
}
.Edit_Area a img {
    width: 100%; /* 子要素の幅を50%に設定 */
    box-sizing: border-box; /* パディングやボーダーを含めた幅計算 */
}
</style>
</head>
<body class="app">

<div class="header">
            <h1>Welcome, <?php echo htmlspecialchars($user['name']); ?>!</h1>
            <p>Email: <?php echo htmlspecialchars($user['email']); ?></p>
            <img src="<?php echo htmlspecialchars($user['picture']); ?>" alt="Profile Picture">
</div>

<script>
</script>
</body>
</html>
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?