【開発メモ】【Docker Toolbox】LaravelのSocialiteパッケージでソーシャルログイン機能の実装

  • 2020.03.23
  • Web
【開発メモ】【Docker Toolbox】LaravelのSocialiteパッケージでソーシャルログイン機能の実装

今回LaravelのSocialiteパッケージを使って、Googleのソーシャルログイン機能を実装してみました。

私のPCはWindows Home10なので、Dockerを使用するにはDocker Toolbox一択。

ここ最近Dockerを使用するメリットがあまり感じられなく、MAMPやXAMPPでいいんじゃないかなと思ったりしながら、現在もDocker Toolboxを使い続けております。

Docker Toolboxを使う上で、一番のデメリットだと感じるのはDockerMachineに192.168.99.100が割り当てられること。

案の定それによって詰まりました。Googleのソーシャルログイン機能の手順とその他詳細をお伝えしたいと思います。私と同じような環境で作業している方の参考になれば幸いです。

環境

・PC : Windows home 10
・Docker: version19.03.1(Docker Toolbox)
・Laradock
・Laravel: version6.12.0
・nginx: version1.17.7

これらの記事で環境を構築しました。

Googleソーシャルログイン実装手順

Googleの設定

Google API Consoleにアクセスして、プロジェクトの作成をします。
  • 「プロジェクト名」に任意のプロジェクト名を入力
  • 「場所」は組織なしを選択
  • 「作成」を押下

プロジェクトが作成されたことを確認します。

左上のハンバーガーメニューから「APIとサービス」、「OAuth同意画面」を選択します。

「User Type」で「外部」を選択して、作成を押下します。

「アプリケーション名」に任意の名前を入力して、保存を押下します。

  • 左側から「認証情報」を選択
  • 「認証情報を作成」を選択
  • 「OAuthクライアントID」を選択

OAuthクライアントIDの作成画面で

  • 「アプリケーションの種類」で「ウェブアプリケーション」をプルダウンから選択
  • 「名前」は 「OAuth同意画面」 で任意でつけた「アプリケーション名」を入力
  • 「承諾済みのリダイレクトURI」で「http://localhost/login/google/callback」を入力
  • 「作成」を押下

OAuthクライアントが作成できますので、「クライアントID」と「クライアントシークレット」をメモしときます。

Laravel .envの設定

取得した「クライアントID」と「クライアントシークレット」 をLaravelの.envファイルに入力します。

project-folder
 └── laradock
 └── laravel
            └── .env 
GOOGLE_CLIENT_ID=クライアントID
GOOGLE_CLIENT_SECRET=クライアントシークレット

Laravel Socialiteパッケージのインストールと設定

laradockディレクトリで以下のコマンドを叩き、 workspaceコンテナ に入ります。

$ docker-compose exec workspace bash

以下のコマンドで、Laravel Socialiteパッケージをインストールします。

# composer require laravel/socialite
Using version ^4.3 for laravel/socialite
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
・
・
・
略
・
・
・
Package manifest generated successfully.

config/services.phpの設定をします。

project-folder
 └── laradock
 └── laravel
           └── config
                     └── services.php
<?php

return [
// 略
    'google' => [
        'client_id' => env('GOOGLE_CLIENT_ID'),
        'client_secret' => env('GOOGLE_CLIENT_SECRET'),
        'redirect' => env('APP_URL') . '/login/google/callback',
    ],

];

Routing

project-folder
 └── laradock
 └── laravel
      └── routes
           └── web.php
<?php

//略

//ここから追加
Route::prefix('login')->name('login.')->group(function () {
    Route::get('/{provider}', 'Auth\LoginController@redirectToProvider')->name('{provider}');
    Route::get('/{provider}/callback', 'Auth\LoginController@handleProviderCallback')->name('{provider}.callback');
});
//ここまで追加

login/{provider}とlogin/{provider}/callbackの2つのパスを用意します。

Controller

project-folder
 └── laradock
 └── laravel
      └── app
             └── Http
                    └── Controllers
                                  └── Auth
                                         └── LoginController.php
<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
//ここから追加
use App\User;
//ここまで追加
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
//ここから追加
use Illuminate\Http\Request;
use Laravel\Socialite\Facades\Socialite;
//ここまで追加

class LoginController extends Controller
{
    //略
    //ここから追加
    public function redirectToProvider(string $provider)
    {
        return Socialite::driver($provider)->redirect();
    }

    public function handleProviderCallback(Request $request, string $provider)
    {
        $providerUser = Socialite::driver($provider)->stateless()->user();
 
        $user = User::where('email', $providerUser->getEmail())->first();
 
        if ($user) {
            $this->guard()->login($user, true);
            return $this->sendLoginResponse($request);
        }
    }
    //ここまで追加
}

redirectToProviderメソッドで、Googleのサーバーにソーシャルログインをしにいっています。

handleProviderCallbackメソッドで、 Googleのサーバーからユーザー情報を取得して、その情報をもとにDBにユーザーが存在しているか確認をしています。

DBにユーザーが存在していれば、ログインを許可します。

View

project-folder
 └── laradock
 └── laravel
            └── resources
                        └── views
                                └── auth
                                        └── login.blade.php
@extends('layouts.app')

@section('content')
{{-- 略 --}}
                        <div class="form-group row mb-0">
                            <div class="col-md-8 offset-md-4">
                                <button type="submit" class="btn btn-primary">
                                    {{ __('Login') }}
                                </button>
                  {{-- ここから追加 --}}
                                <a href="{{ route('login.{provider}', ['provider' => 'google']) }}" class="btn btn-danger">
                                    Googleでログイン
                                </a>
                  {{-- ここまで追加 --}}
{{-- 略 --}}
@endsection

laravel/uiパッケージをインストールすると、デフォルトで作成されるlogin.blade.phpに「Googleでログイン」ボタンを設置しました。

ポートフォワーディング

ただ、このままだとGoogleのソーシャルログイン機能を利用することはできません。

簡単に図にしてみました。

「Googleの設定」で「承諾済みのリダイレクトURI」を「http://localhost/login/google/callback」にしました。

Laravelアプリケーションの実行環境のIPアドレスは192.168.99.100なので、Googleのソーシャルログイン機能を利用するためには、localhostからポートフォワーディングする必要があります。

ポートフォワーディングの設定

管理者権限でコマンドプロンプトを開いて、以下のコマンドを叩きます。

>netsh interface portproxy add v4tov4 listenport=80 listenaddress=127.0.0.1 connectport=80 connectaddress=192.168.99.100

>netsh interface portproxy show v4tov4

ipv4 をリッスンする:         ipv4 に接続する:

Address         Port        Address         Port
--------------- ----------  --------------- ----------
127.0.0.1       80          192.168.99.100  80

Googleソーシャルログイン機能の利用確認

ポートフォワーディングをすると、Laravelのアプリケーションにアクセスするためには、192.168.99.100ではなくlocalhostになります。

事前にGoogleアカウントを持つユーザーで登録してください。

「Googleでログイン」を押下します。

登録したアカウントを選択します。

ログインに成功しました。

まとめ

僕のような初心者でも意外と簡単にGoogleのソーシャルログイン機能を利用することができました。

ただ、僕のようにローカル環境にWindowsでDocker Toolboxを使用している方は、ポートフォワーディングをして通信の転送をする必要があるのが面倒ですね。

今回参考にさせていただいた教材は下記になります。

Laravel(+Vue.js)でSNS風Webサービスを作ろう!

https://www.techpit.jp/p/laravel-vue-sns

とても説明がわかりやすくおすすめです!

以上です。