GoogleアカウントでログインできるWebサービスを作ろう！

## はじめに
今回は、GoogleのOAuth 2.0を使ってGoogleアカウントでログインできるWebサービスを、HTML、JavaScript、Python（Flask）を使って作成する方法をご紹介します。

初心者でも安心して進められるように、Google API Consoleの設定から、実際のプログラム作成までの手順を丁寧に解説していきます。

## 画面イメージ
![スクリーンショット 2024-09-19 18.32.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75802/6e8cec28-8377-55f4-35b6-28ab9956a587.png)

![スクリーンショット 2024-09-19 18.22.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75802/d5cb69b0-8b84-73d4-2322-5cb259f5b38d.png)

![スクリーンショット 2024-09-19 18.22.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75802/2656de62-c40e-a8c5-bd24-071124127809.png)

![スクリーンショット 2024-09-19 18.32.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75802/191dc447-1543-0007-03bf-f2f068a02719.png)



---

## 1. Google APIの準備

GoogleのOAuth 2.0を使用するために、Google Cloud Consoleでプロジェクトを作成し、必要なAPIを有効化します。

### 1.1 Google Cloud Consoleでプロジェクトを作成

まず、[Google Cloud Console](https://console.cloud.google.com/)にアクセスして、Google APIを利用するためのプロジェクトを作成します。

#### 手順:
1. **Google Cloud Console**にアクセスし、Googleアカウントでログインします。
2. 右上にある「**プロジェクトを選択**」ボタンをクリックします。
3. 表示されたダイアログボックスの右上にある「**新しいプロジェクト**」をクリックします。
4. プロジェクト名を入力します（例: "Google Login App"）。
5. 必要に応じて、組織やロケーションを設定します。
6. 「**作成**」ボタンをクリックしてプロジェクトを作成します。

### 1.2 OAuth同意画面の設定

Googleアカウントを使用するアプリでは、ユーザーに許可を求める「**OAuth同意画面**」の設定が必要です。この画面では、アプリの名前や許可を求めるスコープ（アクセス権）をユーザーに提示します。

#### 手順:
1. 左側メニューの「**APIとサービス**」をクリックし、次に「**OAuth同意画面**」を選択します。
2. **ユーザータイプ**として、「**外部**」を選択します（外部ユーザーに対してGoogleログインを提供する場合）。
3. 以下の情報を入力します。
   - **アプリケーション名**: 任意のアプリ名を入力します（例: "Google Login App"）。
   - **サポートメールアドレス**: 管理者連絡用のメールアドレスを選択します。
4. 「**保存して次へ**」をクリックします。
5. **スコープの追加**ページで、デフォルトのままでOKです。「**保存して次へ**」をクリックします。
6. **テストユーザー**の追加ページもそのままスキップして「**保存して次へ**」をクリックします。
7. 最後に「**ダッシュボードに戻る**」をクリックして完了です。

### 1.3 認証情報の作成

次に、Google OAuth 2.0を利用するための**クライアントID**と**クライアントシークレット**を作成します。

#### 手順:
1. 左側メニューの「**APIとサービス**」をクリックし、「**認証情報**」を選択します。
2. 上部の「**+ 認証情報を作成**」ボタンをクリックし、「**OAuth 2.0 クライアントID**」を選択します。
3. **アプリケーションの種類**は「ウェブアプリケーション」を選びます。
4. **名前**は任意で（例: "Google Login Web App"）。
5. **承認済みのリダイレクトURI**に、FlaskアプリのリダイレクトURL（例: `http://localhost:5000/callback`）を追加します。
6. 「**作成**」ボタンをクリックすると、**クライアントID**と**クライアントシークレット**が表示されます。
7. **クライアントID**と**クライアントシークレット**をメモして、後でプログラムに使用します。
8. 「**JSONでダウンロード**」ボタンをクリックし、`client_secret.json`ファイルをプロジェクトディレクトリに保存します。

### 1.4 必要なAPIの有効化

Googleログインを実装するためには、**Google People API**を有効にする必要があります。

#### 手順:
1. 左側のメニューから「**APIとサービス**」→「**ライブラリ**」をクリックします。
2. 検索バーに「Google People API」と入力して検索します。
3. 「Google People API」を選択し、「**有効にする**」ボタンをクリックします。

これで、Google APIの準備が完了です。

---

## 2. プロジェクトのセットアップ

### 2.1 必要なツールのインストール

以下のツールを使います。インストールして準備しましょう。

```bash
pip install Flask requests google-auth google-auth-oauthlib google-auth-httplib2
```

### 2.2 ディレクトリ構成

ディレクトリ構成は以下のようになります。

```
google-login-app/
│
├── app.py                # メインのFlaskアプリケーション
├── client_secret.json     # Google OAuth 2.0のクライアントシークレットファイル
├── requirements.txt       # 必要なパッケージ一覧
├── templates/             # HTMLテンプレートを格納するディレクトリ
│   └── index.html         # ログインボタンを含むホームページ
└── static/                # JavaScriptやCSSファイルを格納するディレクトリ
```

---

## 3. プログラムの作成

### 3.1 `app.py` の作成

次に、PythonのFlaskを使ったサーバーを作成します。GoogleのOAuth 2.0を使って、Googleアカウントでログインできるようにします。

```python
from flask import Flask, redirect, url_for, session, request, render_template
from google.oauth2 import id_token
from google_auth_oauthlib.flow import Flow
from google.auth.transport import requests as google_requests
import os

app = Flask(__name__)
app.secret_key = os.urandom(24)

# Google OAuth 2.0の設定
os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "1"
GOOGLE_CLIENT_ID = "あなたのクライアントID"
GOOGLE_CLIENT_SECRET = "あなたのクライアントシークレット"
REDIRECT_URI = "http://localhost:5000/callback"

flow = Flow.from_client_secrets_file(
    'client_secret.json',
    scopes=["openid", "https://www.googleapis.com/auth/userinfo.profile", "https://www.googleapis.com/auth/userinfo.email"],
    redirect_uri=REDIRECT_URI
)

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/login')
def login():
    authorization_url, state = flow.authorization_url()
    session['state'] = state
    return redirect(authorization_url)

@app.route('/callback')
def callback():
    flow.fetch_token(authorization_response=request.url)

    if not session['state'] == request.args['state']:
        return 'State mismatch error', 400

    credentials = flow.credentials
    request_session = google_requests.Request()

    id_info = id_token.verify_oauth2_token(
        credentials.id_token, request_session, GOOGLE_CLIENT_ID
    )

    session['google_id'] = id_info.get("sub")
    session['email'] = id_info.get("email")
    session['name'] = id_info.get("name")

    return redirect(url_for('profile'))

@app.route('/profile')
def profile():
    if 'google_id' not in session:
        return redirect(url_for('index'))

    user_info = {
        'name': session.get('name'),
        'email': session.get('email')
    }

    return render_template('profile.html', user=user_info)

@app.route('/logout')
def logout():
    session.clear()
    return redirect('/')

if __name__ == '__main__':
    app.run(debug=True)
```

### 3.2 HTMLファイルの作成

次に、Googleログインボタンを含むシンプルなHTMLページを作成します。

#### `templates/index.html`

```html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Googleログイン</title>
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
  <style>
    body {
      background-color: #f7f7f7;
    }
    .container {
      margin-top: 100px;
      text-align: center;
    }
   

 .login-box {
      padding: 30px;
      background-color: white;
      box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);
      border-radius: 10px;
    }
    .login-btn {
      background-color: #4285F4;
      color: white;
      font-size: 1.2em;
    }
    .login-btn:hover {
      background-color: #357ae8;
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="login-box">
      <h1 class="mb-4">Googleアカウントでログイン</h1>
      <button id="login-btn" class="btn login-btn btn-lg">Googleでログイン</button>
    </div>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>
  <script>
    document.getElementById('login-btn').addEventListener('click', function() {
      window.location.href = '/login';
    });
  </script>
</body>
</html>
```

### 3.3 ログイン成功後のページを作成

ログインが成功したら、プロフィールページにリダイレクトして、ユーザーの名前とメールアドレスを表示します。

#### `templates/profile.html`

```html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>プロフィール</title>
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
  <style>
    body {
      background-color: #f7f7f7;
    }
    .container {
      margin-top: 100px;
      text-align: center;
    }
    .profile-box {
      padding: 30px;
      background-color: white;
      box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);
      border-radius: 10px;
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="profile-box">
      <h1 class="mb-4">ようこそ, {{ user.name }} さん!</h1>
      <p>メールアドレス: {{ user.email }}</p>
      <a href="/logout" class="btn btn-danger">ログアウト</a>
    </div>
  </div>
</body>
</html>
```

---

## 4. アプリケーションの起動

最後に、Flaskアプリケーションを起動します。

```bash
flask run
```
または
```bash
python app.py
```

これで、Googleアカウントを使ったログインができるWebサービスが起動します。



## 5. 画面確認
http://localhost:5000/

画面イメージの通りに表示されます。


## まとめ
今回は、Google OAuth 2.0を使ってGoogleアカウントでログインできるWebサービスを作成しました。HTML、JavaScript、Python（Flask）を使って簡単に実装できますので、ぜひ挑戦してみてください！