laravel5.7で、sociliteを作ってソーシャルログイン(twitterやfacebookのアカウントでログイン)できるようにしてみた
参考URL
https://urashita.com/archives/8848
https://qiita.com/niever66/items/d2060d9424f59b887763
0, 各SNSのアカウントで、開発用のプロジェクト生成して、認証キーを取得する
https://apps.twitter.com/
なんか色々と規約が変わって面倒なので、以前作っておいたTwitter Appsを流用
https://developers.facebook.com/apps/
右上のマイアプリをクリックしてプロジェクト生成して、Facebookアカウントでログイン出来るように登録する(サイトurlやコールバック先を設定)
1, laravel標準のログイン認証を実装する
php artisan make:auth
2, ソーシャルログイン用のパッケージをインストール
composer require laravel/socialite
3, socialiteでfacebookログインすると、漢字本名じゃなくてローマ字表記で取得される対策
たった一行修正するだけなのに大騒ぎだ。でもvendorフォルダ以下を直接修正するとupdateで消えちゃうしな…。
以下の3ファイルを生成してオーバーライトする
php artisan make:provider FacebookProvider
app/Socialite/SocialiteManager.php
app/Socialite/SocialiteServiceProvider.php
4, config/app.phpにプロバイダとエイリアスのショートカットを記述(3で作った自作providerを指定)
1 2 3 4 5 6 7 8 9 |
'locale' => 'ja', //facebook本名を漢字にするため(中国とか他の国の言語でも行けそう) 'providers' => [ // facebookだと本名がローマ字なので、漢字で取得できるように修正 App\Socialite\SocialiteServiceProvider::class, ], 'aliases' => [ 'Socialite' => App\Socialite\SocialiteServiceProvider::class, ], |
5, config/services.phpと.envにKEYを記述
※callback(redirect)は、twitter連携アプリに登録したURLじゃないと弾かれる!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
'twitter' => [ 'client_id' => env('TWITTER_CLIENT_ID'), 'client_secret' => env('TWITTER_CLIENT_SECRET'), 'redirect' => env('TWITTER_URL'), ], 'facebook' => [ 'client_id' => env('FACEBOOK_ID'), 'client_secret' => env('FACEBOOK_SECRET'), 'redirect' => env('FACEBOOK_CALLBACKURL'), ], TWITTER_CLIENT_ID=aaaaaaaaaa TWITTER_CLIENT_SECRET=bbbbbbbbb TWITTER_URL=http://localhost/auth/login/callback/twitter FACEBOOK_ID=aaa FACEBOOK_SECRET=bbb FACEBOOK_CALLBACKURL=https://localhost/auth/login/callback/facebook |
6, ログイン画面にソーシャルボタンを追加
1 2 |
<link rel="stylesheet" href="{{ secure_asset('/css/bootstrap.min.css') }}"> <script src="{{ secure_asset('/js/jquery-3.1.1.min.js') }}"></script> |
7, routes/web.phpにルーティングを記述
1 2 3 4 5 6 |
//Twitter Route::get('auth/login/twitter', 'Auth\SocialController@getTwitterAuth'); Route::get('auth/login/callback/twitter', 'Auth\SocialController@getTwitterAuthCallback'); //Facebook Route::get('auth/login/facebook', 'Auth\SocialController@getFacebookAuth'); Route::get('auth/login/callback/facebook', 'Auth\SocialController@getFacebookAuthCallback'); |
8, app/Http/Controllers/Auth/SocialController.phpを新規作成
php artisan make:controller Auth\SocialController
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 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
<?php namespace App\Http\Controllers\Auth; use Illuminate\Http\Request; use App\Http\Controllers\Controller; use Socialite; use App\User; use Auth; use Illuminate\Foundation\Auth\AuthenticatesUsers; use Illuminate\Contracts\Auth\Authenticatable; class SocialController extends Controller { // twitterにリダイレクトして、許可をもらう public function getTwitterAuth() { return Socialite::driver('twitter')->redirect(); } // 許可OKなら、ここに戻ってきてuser情報を取得する public function getTwitterAuthCallback() { try { $user = Socialite::driver('twitter')->user(); } catch (Exception $e) { return redirect('auth/login/twitter'); } // ソーシャルIDでログインする $authUser = $this->findOrCreateTwitterUser($user); Auth::login($authUser, true); return redirect()->route('home'); } // twitterユーザIDでUsersテーブルを検索、存在しなかったらInsertする private function findOrCreateTwitterUser($twitterUser) { // 既に登録済みなら、レコード情報を使う $authUser = User::where('twitter_id', $twitterUser->id)->first(); if ($authUser){ return $authUser; } // 未登録なら登録した後、そのレコード情報を使う return User::create([ 'name' => $twitterUser->nickname, // @abc、表示名は使わない 'twitter_id' => $twitterUser->id, 'twitter_name' => $twitterUser->nickname, // @abc 'avatar' => $twitterUser->avatar_original ]); } // facebookにリダイレクトして、許可をもらう public function getFacebookAuth() { return Socialite::driver('facebook')->redirect(); } // 許可OKなら、ここに戻ってきてuser情報を取得する public function getFacebookAuthCallback() { try { $user = Socialite::driver('facebook')->user(); } catch (Exception $e) { return redirect('auth/login/facebook'); } // ソーシャルIDでログインする $authUser = $this->findOrCreateFacebookUser($user); Auth::login($authUser, true); return redirect()->route('home'); } // facebookユーザIDでUsersテーブルを検索、存在しなかったらInsertする private function findOrCreateFacebookUser($facebookUser) { // 既に登録済みなら、レコード情報を使う $authUser = User::where('facebook_id', $facebookUser->id)->first(); if ($authUser){ return $authUser; } // 未登録なら登録した後、そのレコード情報を使う return User::create([ 'name' => $facebookUser->name, // @abc、表示名は使わない 'facebook_id' => $facebookUser->id, 'facebook_name' => $facebookUser->name, // @abc 'avatar' => $facebookUser->avatar_original ]); } } |
9, このままだとMySQLに登録されないので、登録処理を入れる
app/User.php
1 2 3 |
// MassAssignment(INSERT/UPDATEで入力できるカラムを指定。$fillable=ホワイトリスト、$guarded=ブラックリスト) // protected $fillable= array('name', 'email', 'password'); protected $guarded = array('id'); |
ソーシャルログインのために、emailやpasswordはnullableにしておく
database/migrations/xxxxx_create_users_table.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
Schema::create('users', function (Blueprint $table) { $table->increments('id'); $table->string('name')->comment('表示名'); $table->string('email')->nullable()->comment('email'); $table->string('password')->nullable()->comment('ログインパスワード'); $table->string('avatar')->nullable()->comment('twitterアイコンのURL'); $table->string('twitter_id')->unique()->nullable()->comment('twitterの内部ID'); $table->string('twitter_name')->nullable()->comment('twitterの@名前、変更出来ない方'); $table->string('facebook_id')->unique()->nullable()->comment('facebookの内部ID'); $table->string('facebook_name')->nullable()->comment('facebookの名前、本名?'); $table->timestamp('email_verified_at')->nullable(); $table->rememberToken(); $table->timestamps(); }); |
10, 画面周りを作る
resources/views/auth/login.phpに追加
1 2 3 4 5 6 |
<a class="btn btn-block btn-social btn-twitter" href="auth/login/twitter"> <span class="fa fa-twitter"></span> Sign in with Twitter </a> <a class="btn btn-block btn-social btn-facebook" href="auth/login/facebook"> <span class="fa fa-facebook"></span> Sign in with Facebook </a> |
なんかソーシャルログイン・ボタンの表示がイマイチだけど、見た目だけなので後回しにしよう。
resources/views/home.phpに追加(取得した名前とアイコンを表示)
1 2 3 4 |
<div> <h4>{{ Auth::user()->name }} </h4> <img src="{{ Auth::user()->avatar }}" height="64" width="64" /> </div> |