0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

今すぐローカル用だけ設定すれば、デプロイを待たずにテストできます。本番 URLは後から追加できます。

はじめに

Spring Boot + Nuxt 3 で構築したWebアプリに「Googleアカウント連携(OAuth)」を実装しました。
ローカル開発環境での設定から、AWS ECS + Terraform を使った本番デプロイまでの流れをまとめます。

この記事でわかること

  • Google OAuth 2.0 の認証フロー
  • Google Cloud Console へのアプリ登録手順
  • ローカル開発環境(Spring Boot)での設定方法
  • AWS Secrets Manager + Terraform を使った本番環境への設定

Google OAuth とは

ユーザーが「Googleでログイン」ボタンを押すと、パスワードをアプリに渡すことなく、Googleが身元を保証してくれる仕組みです。

フローのポイント

要素 役割
client_id アプリの識別子(公開してよい)
client_secret アプリの秘密鍵(絶対に公開しない
redirect_uri Googleが認証後にコードを送る先のURL
state CSRF防止用のランダム文字列(Redisに一時保存)
code 一時的な認証コード(トークンと交換する)

1. Google Cloud Console へのアプリ登録

1-1. プロジェクト作成

Google Cloud Console にアクセスし、新規プロジェクトを作成します。
image.png

image.png

image.png

image.png

image.png

image.png

1-2. OAuth 同意画面の設定

APIとサービス → OAuth 同意画面 を開きます。

ユーザーの種類: 外部
アプリ名: (アプリの名前)
サポートメール: (メールアドレス)

注意: 本番公開前は「テスト」状態のままで、テストユーザーに自分のメールアドレスを追加しておきます。

1-3. OAuth クライアントIDの作成

APIとサービス → 認証情報 → 認証情報を作成 → OAuth クライアントID を選択。

アプリケーションの種類: ウェブアプリケーション
名前: (任意)

承認済みのリダイレクト URI:
  ローカル用: http://localhost:8080/api/v1/auth/oauth/link/GOOGLE/callback
  本番用:     https://your-domain.com/api/v1/auth/oauth/link/GOOGLE/callback

image.png

image.png

ハマりポイント: リダイレクト URI にパスを含める場合、末尾に / を付けてはいけません。Googleに弾かれます。

作成後、クライアントIDクライアントシークレット が表示されます。この2つを次のステップで使います。

2. ローカル開発環境での設定(Spring Boot)

Spring Boot 側の実装

application.yml に以下のプロパティを定義します:

mannschaft:
  google:
    client-id: ${MANNSCHAFT_GOOGLE_CLIENT_ID:}
    client-secret: ${MANNSCHAFT_GOOGLE_CLIENT_SECRET:}
    link-redirect-uri: ${MANNSCHAFT_GOOGLE_LINK_REDIRECT_URI:http://localhost:8080/api/v1/auth/oauth/link/GOOGLE/callback}

Spring Boot の Relaxed Binding により、環境変数 MANNSCHAFT_GOOGLE_CLIENT_ID が自動的に mannschaft.google.client-id にマッピングされます。

環境変数の設定方法(3つのアプローチ)

A. application-local.yml に直書き(シンプルだが git に入れないよう注意)

# application-local.yml(.gitignore に追加すること)
mannschaft:
  google:
    client-id: "your-client-id"
    client-secret: "your-client-secret"

B. ~/.profile に書く(WSL2 や Linux で常駐サーバーを動かす場合)

# ~/.profile に追記
export MANNSCHAFT_GOOGLE_CLIENT_ID="your-client-id"
export MANNSCHAFT_GOOGLE_CLIENT_SECRET="your-client-secret"

起動スクリプト(例: backend-loop.sh)内で ~/.profile を読み込むよう設定します:

#!/bin/bash
export HOME=/home/yourname
source ~/.profile 2>/dev/null || true  # ← これが必要

cd /home/yourname/your-project/backend
while true; do
  ./gradlew bootRun
  sleep 3
done

ハマりポイント: ~/.profile を設定しても起動スクリプトが source していなければ環境変数は読み込まれません。Spring Boot を直接起動する場合は問題ありませんが、ラッパースクリプト経由の場合は要確認です。

C. IntelliJ IDEA / VS Code の実行設定

IDE の実行設定(Run Configuration)に環境変数として直接入力できます。

設定確認

BE を起動して以下の URL を叩いたとき、Google の認証画面に遷移すれば成功です。

GET /api/v1/users/me/oauth/link/GOOGLE/auth-url

client_id が空のまま(設定が読み込まれていない)場合、Googleから以下のエラーが返ります:

エラー 400: invalid_request
Missing required parameter: client_id

3. 本番環境(AWS ECS)での設定

本番環境では、シークレットを安全に管理する必要があります。
client_secret をコードや設定ファイルに直書きすると、git 履歴に残るリスクがあります。

アーキテクチャ

なぜ Secrets Manager を使うのか

方法 問題点
environment ブロックに直書き Terraform の tfstate に 平文で残る
SSM Parameter Store(通常) tfstate に平文が残る(SecureString でも)
Secrets Manager(採用) 箱だけ Terraform で管理、値は別途投入 → tfstate に残らない

Terraform の設定

① Secrets Manager の「箱」を作成

# modules/app/main.tf

resource "aws_secretsmanager_secret" "google_oauth" {
  name                    = "${var.prefix}/google-oauth"
  description             = "Google OAuth credentials (client_id / client_secret)"
  recovery_window_in_days = 7
}

aws_secretsmanager_secret_version は書きません。値は手動投入します。

② ECS タスク定義の secrets ブロックで参照

container_definitions = jsonencode([
  {
    name  = "${var.prefix}-app"
    image = "${aws_ecr_repository.backend.repository_url}:latest"

    # 非秘密の環境変数
    environment = [
      { name = "SPRING_PROFILES_ACTIVE", value = "prod" },
      # ...
    ]

    # 秘密はSecretsManagerから注入(平文をtfstateに残さない)
    secrets = [
      {
        name      = "MANNSCHAFT_GOOGLE_CLIENT_ID"
        valueFrom = "${aws_secretsmanager_secret.google_oauth.arn}:client_id::"
      },
      {
        name      = "MANNSCHAFT_GOOGLE_CLIENT_SECRET"
        valueFrom = "${aws_secretsmanager_secret.google_oauth.arn}:client_secret::"
      }
    ]
  }
])

デプロイ手順

Step 1: Google Console に本番用リダイレクト URI を追加

https://your-domain.com/api/v1/auth/oauth/link/GOOGLE/callback

Step 2: Terraform を apply

cd infra/terraform/envs/prod
terraform apply

Step 3: Secrets Manager に値を投入

aws secretsmanager put-secret-value \
  --secret-id "your-prefix/google-oauth" \
  --secret-string '{
    "client_id": "your-client-id.apps.googleusercontent.com",
    "client_secret": "your-client-secret"
  }'

Step 4: ECS にデプロイ

タスクが起動するとき、ECS が Secrets Manager から値を自動的に取得して環境変数として渡します。Spring Boot には MANNSCHAFT_GOOGLE_CLIENT_ID / MANNSCHAFT_GOOGLE_CLIENT_SECRET として届きます。

まとめ

環境 設定方法 シークレットの置き場所
ローカル(IDE) Run Configuration に直接入力 ローカルのみ
ローカル(常駐サーバー) ~/.profile に export ローカルのみ
本番(AWS ECS) Terraform で Secrets Manager を定義し ECS に注入 AWS Secrets Manager

やってしまいがちなミス集

  • client_secretapplication.yml に書いてコミット → git 履歴から漏洩します
  • リダイレクト URI の末尾に / を付ける → Google に弾かれます
  • 起動スクリプトが ~/.profile を読んでいない → 環境変数が Spring Boot に届きません
  • Terraform に aws_secretsmanager_secret_version を書く → tfstate に平文が残ります
  • 本番用リダイレクト URI を Google Console に追加し忘れる → 本番でだけ OAuth が動きません

参考

0
0
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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?