どうもこんにちは。
ソーシャルログインをやりたいというクライアントのご意向があり
どうもLaravelでは簡単に実装できるらしい、ということもあり、試してみました。
今回は、LINE/twitter/Googleでやってみたいと思います。
Laravelのインストールと.envへデータベースの設定が終わっている前提です。
ちなみに、今回のLaravelは5.8を使用しています。
目次
認証フォームの作成
Laravel標準の認証フォームを拡張しようと思うので、
なにはともあれコマンド実行
1 |
php artisan make:auth |
ねんのため、サーバを起動して、確認をしてみましょう。
1 |
php artisan serv |
で、http://localhost:8000/login
にアクセス。
はい。とりあえずそのまんまです。
次へ。
Socialite インストール
こいつがソーシャルログインの元締めのようです。
Composerを使ってインストールしましょう。
1 |
composer require laravel/socialite |
インストールできたら、次はドライバをインストールします。
LINE/twitter/Googleと欲張るので、3回コマンド実行です。
1 2 3 |
composer require socialiteproviders/line composer require socialiteproviders/twitter composer require socialiteproviders/google |
では、次。
サービスプロバイダの登録
config/app.phpに下記を追記します。
1 2 3 4 5 6 7 8 9 10 |
: 'providers' => [ : /* * Package Service Providers... */ \SocialiteProviders\Manager\ServiceProvider::class, // <- ここ : ], : |
イベントリスナの登録
app/Providers/EventServiceProvider.phpにリスナを登録します。
1 2 3 4 5 6 7 8 9 10 11 12 |
protected $listen = [ Registered::class => [ SendEmailVerificationNotification::class, ], // ここから \SocialiteProviders\Manager\SocialiteWasCalled::class => [ 'SocialiteProviders\Line\LineExtendSocialite@handle', 'SocialiteProviders\Twitter\TwitterExtendSocialite@handle', 'SocialiteProviders\Google\GoogleExtendSocialite', ], // ここまで ]; |
SNSプロバイダごとの設定
プロバイダごとに発行されるclient ID, client secret, callback urlを設定します。
基本的には.envに定義しておいて、config/service.phpで読み込むようにするのが良いですね。
.env
1 2 3 4 5 6 7 8 9 10 11 |
LINE_CLIENT_ID=[チャネル基本設定 の Channel ID] LINE_CLIENT_SECRET=[チャネル基本設定 の Channel Secret] LINE_CALLBACK_URL=[リダイレクト設定 の Callback URL] TWITTER_CLIENT_ID=[Keys and Tokens の Consumer API Keys(API key) ] TWITTER_CLIENT_SECRET=[Keys and Tokens の Consumer API Keys(API secret key) ] TWITTER_CALLBACK_URL=[App Details の Callback URL] GOOGLE_CLIENT_ID=[クライアントID] GOOGLE_CLIENT_SECRET=[クライアントシークレット] GOOGLE_CALLBACK_URL=[承認済みのリダイレクト URI] |
config/service.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
: // ここから 'line' => [ 'client_id' => env('LINE_CLIENT_ID'), 'client_secret' => env('LINE_CLIENT_SECRET'), 'redirect' => env('LINE_CALLBACK_URL'), ], 'twitter' => [ 'client_id' => env('TWITTER_CLIENT_ID'), 'client_secret' => env('TWITTER_CLIENT_SECRET'), 'redirect' => env('TWITTER_CALLBACK_URL'), ], 'google' => [ 'client_id' => env('GOOGLE_CLIENT_ID'), 'client_secret' => env('GOOGLE_CLIENT_SECRET'), 'redirect' => env('GOOGLE_CALLBACK_URL'), ], // ここまで : |
データベース
make:authで使用するUserテーブルにちょっと手を加えます。
パスワードが不要なので、passwordカラムをnullableに変更しましょう。
その前に、doctrine/dbalをインストールします。
1 |
composer require doctrine/dbal |
インストールできたら、migration用ファイルを作成します。
まずはコマンド。
1 |
php artisan make:migration prepare_user_table_for_social_login --table=users |
作成されたファイルを編集します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
<?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class PrepareUserTableForSocialLogin extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::table('users', function (Blueprint $table) { // $table->string('password')->nullable()->change(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table('users', function (Blueprint $table) { // $table->string('password')->nullable(false)->change(); }); } } |
ここまできたら、migrate。
1 |
php artisan migrate |
データベースを確認して、思い通りになっていたらOKです。
実装
では、実装です。
LoginController
app/Http/Controllers/Auth/LoginController.phpに下記を追加します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
//ログインボタンからリンク public function socialLogin($social) { return Socialite::driver($social)->redirect(); } //Callback処理 public function handleProviderCallback($social) { //ソーシャルサービス(情報)を取得 $userSocial = Socialite::driver($social)->stateless()->user(); //emailで登録を調べる $user = User::where(['email' => $userSocial->getEmail()])->first(); //登録(email)の有無で分岐 if($user){ //登録あればそのままログイン(2回目以降) Auth::login($user); return redirect('/home'); }else{ //なければ登録(初回) $newuser = new User; $newuser->name = $userSocial->getName(); $newuser->email = $userSocial->getEmail(); $newuser->save(); //そのままログイン Auth::login($newuser); return redirect('/home'); } } |
ルーティング
routes/web.phpに下記を追記します。
1 2 |
Route::get('login/{provider}', 'App\Http\Controllers\Auth\LoginController@socialLogin'); Route::get('login/{provider}/callback', 'App\Http\Controllers\Auth\LoginController@handleProviderCallback'); |
ビュー
ログインのビューに各プロバイダログイン用のリンクを設置します。
アイコンはfont-awesomeのを使おうと思うので、
まずはresources/views/layouts/login.blade.phpにCSS読み込み部分を追記します。
font-awesomeについてはこちら ⇒ Font Awesome
1 2 3 4 5 6 7 8 |
: <!-- Styles --> <link href="{{ asset('css/app.css') }}" rel="stylesheet"> {{--ここ--}} <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.0/css/all.css" integrity="sha384-Mmxa0mLqhmOeaE8vgOSbKacftZcsNYDjQzuCOm6D02luYSzBG8vpaOykv9lFQ51Y" crossorigin="anonymous"> </head> <body> : |
次にresources/views/auth/login.blade.phpを編集します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
: <div class="card-body"> <form method="POST" action="{{ route('login') }}"> @csrf {{--ここから--}} <div class="form-group row"> <label for="name" class="col-sm-4 col-form-label text-md-right">Login With</label> <a href="{{ url('login/line')}}" class="btn btn-social-icon btn-line"><i class="fab fa-line fa-5x"></i></a> <a href="{{ url('login/twitter')}}" class="btn btn-social-icon btn-twitter"><i class="fab fa-twitter fa-5x"></i></a> <a href="{{ url('login/google')}}" class="btn btn-social-icon btn-google"><i class="fab fa-google fa-5x"></i></a> </div> {{--ここまで--}} <div class="form-group row"> <label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label> : |
確認
さて、ここまで来たら、もう一度ログインページを覗いてみると・・・?
いけてるやん!
ためしに、LINEのアイコンをぽちっとな。
おお。
あとは権限を許可したら・・・
Woops!なんかエラー出ました。
GuzzleHttp \ Exception \ RequestException
cURL error 60: SSL certificate problem: unable to get local issuer certificate (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)
ググってみると解決方法が! ⇒ cURL error 60: SSL certificate problem: unable to get local issuer certificate (see http: curl.haxx.se libcurl c libcurl errors.html)
上記のサイトによると
・https://curl.haxx.se/ca/cacert.pemから証明書をDLして保存
・php.iniに設定して再起動 Finish!
でOKとのこと。
php.iniを編集し、サーバを再起動して各アイコンの挙動を確認します。
LINE:エラー
⇒emailが返ってこなかったので。LINE側の設定で何とかできそうなので放置。
emailが返ってこなかった時の対処は考えておこう。
Twitter:成功!
Google:エラーのち成功、でもやっぱり・・・?
⇒まずは失敗について。どうやらlocalhostが良くないみたい。
ngrokを使用することで、成功したことを確認。
ngrokについては、公式サイトをどうぞ ⇒ ngrok – secure introspectable tunnels to localhost
⇒ngrokを使用することで解決はしたけども、よくよく調べると、
Google+ APIを使用していることが判明。これはちょっとまずい。
composer require socialiteproviders/google
でインストールされるのは
Google+用のものみたいです。
ソースをちょいちょいっと改造したら解決しそうな雰囲気なので
それは後日やるってことで、今回はおしまい。
まとめ
ウソみたいなコードの少なさでSNS認証ができます。
SocialiteProviderにはさまざまなサービス用のものが用意されています。
Yahooとか、Youtubeとか、LinkedInとか、Facebookとか、Weiboなんかも。
これは使うしかないですね。
R.TANAKAがお届けしました。