Laravelの自作アプリにGoogleログインを実装する

# はじめに
自作のオリジナルアプリにGoogleログイン機能を実装したので、実装方法をまとめていきます。
参考にした資料は、最後にまとめて記載しています。

なお、制作したアプリはこれです↓
https://kondate.work
（献立を管理できるアプリです。よかったら使ってみて下さいw　改善要望もぜひ！）

# 作業環境
　Laravel 8.20.1
　ローカルにdockerで開発環境を構築
　　DB:mysql  Ver 14.14 Distrib 5.7.31
　　webサーバ：nginx　1.18.0

ローカル開発環境を構築するにあたっては、こちらの記事を参考にしました↓

参考：
絶対に失敗しないDockerでLaravel+Vueの実行環境（LEMP環境）を構築する方法〜前編〜
https://qiita.com/shimotaroo/items/29f7878b01ee4b99b951
絶対に失敗しないDockerでLaravel+Vueの実行環境（LEMP環境）を構築する方法〜後編〜
https://qiita.com/shimotaroo/items/679104b7e00dd9f89907


# google認証情報の作成
googleアカウントにログインし、GCPにアクセスします。
https://console.cloud.google.com/
メニューの「APIとサービス」→「認証情報」を選択します。
![スクリーンショット 2020-12-25 8.47.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599831/786fbf84-104f-d59c-4344-b25e8418e795.png)

「認証情報を作成」をクリック
→「OAuthクライアントID」
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599831/44468b86-c3a7-4276-73fa-966c4e6a781f.png" alt="スクリーンショット 2020-12-25 8.58.16.png" width="500">

1. アプリケーションの種類<br>
→ウェブアプリケーション
2. 名前<br>
→任意の名前（わかりやすいようにつけて下さい）
3. 承認済みのJavaScript生成元 URI<br>
→googleへのアクセスを許可するホストを登録して下さい。ここでは、ローカル環境なのでloaclhostを指定しています。
4. 承認済みのリダイレクトURI<br>
→認証後のコールバックURLです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599831/5eddeaed-72dc-68c2-cad8-64a193eef241.png" alt="スクリーンショット 2020-12-25 9.12.38.png" width="400">

作成ボタンを押すと、認証情報の設定が完了です。

認証情報が作成されると、クライアントIDとクライアントシークレットが発行されます。
後ほどの実装で使うので、控えておきましょう。

# 実装

## Laravelプロジェクトのインストール

Laravelのプロジェクトを新規作成していきます。

```
composer create-project laravel/laravel —-prefer-dist
```

## ログイン画面の作成

Laravel5.0系で使えていた`php artisan make:auth`は6.0以上で使えなくなっているので、以下のコマンドを実行してください。

laravel/uiをインストール、認証関連のビューファイルを作成します。

```
composer require laravel/ui
php artisan ui vue --auth
```

css,jsのビルドを行います。

```
npm install
npm run dev
```

参考：
https://note.com/koushikagawa/n/n1b5bb4a69514

ログイン画面が完成です。
localhostにアクセスして、画面を確認してみて下さい。
ポート番号は、Webサーバに設定したものを指定しましょう。
http://localhost:ポート番号/login
![スクリーンショット 2020-12-24 21.14.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599831/e1da7022-65df-b8fe-8574-53814b6c8bcc.png)


## Socialiteをインストール
今回は、Google認証にSocialiteライブラリを使って実装をしていきます。
以下コマンドでSocialiteをインストールします。

```
composer require laravel/socialite
```

Socialiteをservice providerに追記します。

```config/app.php
return [

    'providers' => [
        Laravel\Socialite\SocialiteServiceProvider::class, // 追加
    ],

    'aliases' => [
        'Socialite' => Laravel\Socialite\Facades\Socialite::class, // 追加
    ],
];

```

これで、`use Socialite`を宣言することでライブラリを使うことができるようになりました。

## コントローラ作成

既存のLoginController.phpに追記する形でも良いですが、今回はGoogleログイン用にコントローラを作成します。

```
php artisan make:controller GoogleLoginController
```

Googleへのリダイレクト処理と認証後の処理を書いていきます。
ここが今回のメイン処理となります。

大まかな処理の流れとしては、以下のとおりです。
1. ログイン画面の「googleログイン」ボタンをクリック→「redirectToGoogle」が呼ばれる
2. googleにリダイレクト→認証処理
3. 認証成功したらhandleGoogleCallbackにコールバック
4. メールアドレスが一致するユーザが存在すればそのままログイン、存在しなければ新規ユーザ作成

```app\Http\Controllers\GoogleLoginController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash; // 追加
use Illuminate\Support\Facades\Auth; // 追加
use Socialite; // 追加
use App\Models\User; //追加

class GoogleLoginController extends Controller
{
    public function redirectToGoogle()
    {
        // Googleへのリダイレクト→Google側で認証処理
        return Socialite::driver('google')->redirect();
    }

    public function handleGoogleCallback()
    {
        // googleのユーザ情報を取得
        $googleUser = Socialite::driver('google')->stateless()->user();
        // email が合致するユーザをDBから取得
        $user = User::where('email', $googleUser->email)->first();
        // DBに該当するユーザがなければ新しくユーザを作成
        if ($user == null) {
            $user = $this->createUser($googleUser);
        }

        // 作成したユーザでログイン処理
        Auth::login($user, true);

        // /homeにリダイレクト
        return redirect('/home');
    }

    public function createUser($googleUser)
    {
        $user = User::create([
            'name'     => $googleUser->name,
            'email'    => $googleUser->email,
            'password' => Hash::make(uniqid()),
        ]);
        return $user;
    }
}
```

## ルーティングの設定
googleへのリダイレクトと認証後の処理にルートを通します。

```resources/routes/web.php
// googleへのリダイレクト
Route::get('/auth/google', 'App\Http\Controllers\GoogleLoginController@redirectToGoogle');
// 認証後の処理
Route::get('/auth/google/callback', 'App\Http\Controllers\GoogleLoginController@handleGoogleCallback');

```

## viewにログインリンクを追加

```resources/views/auth/login.blade.php
<div class="form-group row mb-0">
    <div class="col-md-8 offset-md-4">
        <button type="submit" class="btn btn-primary">
            {{ __('Login') }}
        </button>

        @if (Route::has('password.request'))
            <a class="btn btn-link" href="{{ route('password.request') }}">
                 {{ __('Forgot Your Password?') }}
            </a>
        @endif
        // googleログインボタンを追加
        <a class="btn btn-social btn-google mt-2" href="auth/google">
            <i class="fab fa-google" aria-hidden="true"></i>Googleアカウントでログイン
        </a>
    </div>
</div>
```
装飾用に、Bootstrap、Social Buttons for Bootstrap、fontawesomeを入れておきます。

```resouces/views/layouts/app.blade.php
// Bootstrap
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet">
// Social Buttons for Bootstrap
<link rel="stylesheet" href="css/bootstrap-social.css">
// fontawesome
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.2/css/all.css">
```

一度ログイン画面の確認です。
こんな感じでログインボタンができています。
![スクリーンショット 2020-12-25 7.52.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599831/6c83cb89-e14f-4542-42d3-9a781641fc84.png)


参考：
ソーシャルボタンが手軽に置ける「Social Buttons for Bootstrap」がすごい便利そう
https://qiita.com/sola-msr/items/19f271ef7ba79e4e1cb0


## DBの接続設定

user情報登録用DBの接続設定をします。
作成したDBに合わせて編集して下さい。

```
DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=db_name
DB_USERNAME=db_user
DB_PASSWORD=db_password
```
migrationを実行して`users`テーブルを作ります。

```
php artisan migrate

Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table (31.52ms)
```

## 認証情報の設定
`.env`に、googleの認証情報を追記します。
クライアントIDとクライアントシークレットはGCPを確認して記入して下さい。

コールバックのURLは、`web.php`で指定した認証後の処理を実行するURLです。
（ここでは/login/google/callbackになります。）

```
GOOGLE_CLIENT_ID=クライアントID
GOOGLE_CLIENT_SECRET=クライアントシークレット
GOOGLE_CALLBACK_URL=コールバックのURL
```

configに以下の認証情報を追記します。

```config/service.php

'google' => [
    'client_id' => env('GOOGLE_CLIENT_ID'),
    'client_secret' => env('GOOGLE_CLIENT_SECRET'),
    'redirect' => env('GOOGLE_CALLBACK_URL'),
],
```

viewのテンプレートに、以下の情報を追記します。
クライアントIDは、GCPで各自確認したものを記入して下さい。


```resources/views/layouts/app.blade.php
<body>

    <script src="https://apis.google.com/js/platform.js" async defer></script> // 追加
</body>
```

これで、googleログインの実装が完了です。
お疲れ様でした。

# 参考
Laravel で作ったアプリに Google アカウントでログインする方法（OAuth 2.0）
https://qiita.com/u-dai/items/91df3b923dc82fed5b76

Integrating Google Sign-In into your web app
https://developers.google.com/identity/sign-in/web/sign-in?authuser=1

WEBページに「Googleアカウントでログイン」を実装する
https://qiita.com/kmtym1998/items/768212fe92dbaa384c27