Laravel5ソーシャルログインの機能を実装することがあるかと思います。
今回の記事では、Laravel5でソーシャルログインの機能を実装する方法について紹介します。
Laravel5の環境構築については、下記のページを参照ください。
今回の記事は、下記の記事を作成時点のアプリケーションに作成しているので、Laravel5の知識がない方は、こちらも合わせて読んだ方がわかりやすいかもしれません。また、この記事は、laravel authコマンドを使用して認証システムを実装していることが前提です。こちらの記事に方法が書かれているので、参照してください。
Contents
環境
- CentOS 7.4
- PHP 7.2.7
- MySQL 5.7.22
- Apache 2.4.6
- Laravel 5.5/5.6
- Socialite 3.0
Socialiteとは?
Socialite自体は完全サードパーティのパッケージですが、Laravelが公式でアナウンスしているパッケージです。
Socialiteは以下のSNSのソーシャルログインの機能を提供しています。Socialiteパッケージを導入すると、簡単にOAuth認証を実装する事ができます。
・Facebook
・Twitter
・LinkedIn
・Github
・Google
・Bitbucket
Socialiteのインストール
SocialiteをインストールするためにComposerを使用します。
Laravelプロジェクト内で以下のコマンドを打ちます。
#Laravelのプルジェクトへ cd /laravel_project/ #composerでSocialiteをインストール composer require laravel/socialite
config/app.phpの設定
次にconfig/app.phpファイルの設定を行います。providersの配列の中に以下を追記します。
順番は、どこでも問題ありません。
'providers' => [ . . . Laravel\Socialite\SocialiteServiceProvider::class, ],
次にエイリアスを登録します。同じファイル内のaliasesの配列の中に以下の内容を追加します。
'aliases' => [ . . . 'Socialite' => Laravel\Socialite\Facades\Socialite::class, ],
LoginControllerの修正
次にLoginControllerを修正します。
app/Http/Controllers/Auth/LoginController.phpに次に記載されたメソッドを追加します。また、Socialite、App\User、Authをuseしてください。
use Socialite; use App\User; use Auth; . . . /** * Handle Social login request * * @return response */ public function socialLogin($social) { return Socialite::driver($social)->redirect(); } /** * Obtain the user information from Social Logged in. * @param $social * @return Response */ public function handleProviderCallback($social) { $userSocial = Socialite::driver($social)->user(); $user = User::where(['email' => $userSocial->getEmail()])->first(); if($user){ Auth::login($user); return redirect()->action('HomeController@index'); }else{ return view('auth.register',['name' => $userSocial->getName(), 'email' => $userSocial->getEmail()]); } }
上記のコードのsocialLoginメソッドは、TwitterやFaceBookなどのSNSへリダイレクトするメソッドです。
2番目のhandleProviderCallbackメソッドは、コールバックメソッドです。このメソッドは、最初に、SNSを使用してログインしたユーザの詳細を取得し、ユーザがすでにusersテーブルに存在するかどうかをチェックします。 ユーザーが存在する場合、ユーザーを認証し、ユーザーをhomeにリダイレクトします。 ユーザーが存在しない場合、登録ページにリダイレクトされます。
次にweb.phpにルーティングを登録します。
/routes/web.phpの編集
/routes/web.phpを開き、下記の内容を追加します。
Route::get('/login/{social}','Auth\LoginController@socialLogin')->where('social','twitter|facebook|linkedin|google|github|bitbucket'); Route::get('/login/{social}/callback','Auth\LoginController@handleProviderCallback')->where('social','twitter|facebook|linkedin|google|github|bitbucket');
ルートを設定しました。次にログインページとユーザ登録ページを修正します。
/resources/views/auth/login.blade.phpの修正
/resources/views/auth/login.blade.phpの内容を追加します。
{{ csrf_field() }}の上あたりに追加します。
<div class="form-group"> <label for="name" class="col-md-4 control-label">Login With</label> <div class="col-md-6"> <a href="{{ url('login/facebook') }}" class="btn btn-social-icon btn-facebook"><i class="fa fa-facebook"></i></a> <a href="{{ url('login/twitter') }}" class="btn btn-social-icon btn-twitter"><i class="fa fa-twitter"></i></a> <a href="{{ url('login/google') }}" class="btn btn-social-icon btn-google-plus"><i class="fa fa-google-plus"></i></a> <a href="{{ url('login/linkedin') }}" class="btn btn-social-icon btn-linkedin"><i class="fa fa-linkedin"></i></a> <a href="{{ url('login/github') }}" class="btn btn-social-icon btn-github"><i class="fa fa-github"></i></a> <a href="{{ url('login/bitbucket') }}" class="btn btn-social-icon btn-bitbucket"><i class="fa fa-bitbucket"></i></a> </div> </div>
/resources/views/auth/register.blade.phpの修正
/resources/views/auth/register.blade.phpを修正します。
こちらもテンプレートないの{{ csrf_field() }}の上あたりに下記の内容を追記します。
<div class="form-group"> <label for="name" class="col-md-4 control-label">Register With</label> <div class="col-md-6"> <a href="{{ url('login/facebook') }}" class="btn btn-social-icon btn-facebook"><i class="fa fa-facebook"></i></a> <a href="{{ url('login/twitter') }}" class="btn btn-social-icon btn-twitter"><i class="fa fa-twitter"></i></a> <a href="{{ url('login/google') }}" class="btn btn-social-icon btn-google-plus"><i class="fa fa-google-plus"></i></a> <a href="{{ url('login/linkedin') }}" class="btn btn-social-icon btn-linkedin"><i class="fa fa-linkedin"></i></a> <a href="{{ url('login/github') }}" class="btn btn-social-icon btn-github"><i class="fa fa-github"></i></a> <a href="{{ url('login/bitbucket') }}" class="btn btn-social-icon btn-bitbucket"><i class="fa fa-bitbucket"></i></a> </div> </div>
同時に、nameとemailのformを下記のように書き換えます。
<div class="form-group{{ $errors->has('name') ? ' has-error' : '' }}"> <label for="name" class="col-md-4 control-label">Name</label> <div class="col-md-6"> @if(!empty($name)) <input id="name" type="text" class="form-control" name="name" value="{{$name}}" required autofocus> @else <input id="name" type="text" class="form-control" name="name" value="{{ old('name') }}" required autofocus> @endif @if ($errors->has('name')) <span class="help-block"> <strong>{{ $errors->first('name') }}</strong> </span> @endif </div> </div> <div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}"> <label for="email" class="col-md-4 control-label">E-Mail Address</label> <div class="col-md-6"> @if(!empty($email)) <input id="email" type="email" class="form-control" name="email" value="{{$email}}" required> @else <input id="email" type="email" class="form-control" name="email" value="{{ old('email') }}" required> @endif @if ($errors->has('email')) <span class="help-block"> <strong>{{ $errors->first('email') }}</strong> </span> @endif </div> </div>
/resources/views/layouts/app.blade.phpのhead内に下記の内容を追記します。
これをすることで、ソーシャルボタンが表示されるようになります。
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
各SNSアプリ情報の追加
Twitter Application Management
https://apps.twitter.com/
Facebook for Developers
https://developers.facebook.com/quickstarts/
Google APIs Console
https://console.developers.google.com/apis
Linkedin Developers App
https://www.linkedin.com/developer/apps
github Register a new OAuth application
https://github.com/settings/applications/new
OAuth認証を実装する際にはもちろん、各SNSの認証アプリを作成しておく必要があります。
認証アプリというのは、各SNSのデベロッパーツールなどに登録して、OAuthサービスをつかえるようにする、いわゆる開発者の認証サービスのためのアカウントのようなものです。それぞれのページへ行き、client_idとclient_secretの取得と、redirectURLの登録などを行いましょう。
アカウントやその他情報が取得できたら、それらの情報を設定していきます。
config/services.phpの設定
今回は、Twitterの・FaceBook・Googleの例を示してソーシャルログインの機能を紹介します。
config/services.phpを開き、下記のように編集します。
/** * socialite Settings */ 'twitter' => [ 'client_id' => env('TWITTER_API_KEY'), 'client_secret' => env('TWITTER_API_SECRET'), 'redirect' => env('TWITTER_CALLBACKURL'), ], 'facebook' => [ 'client_id' => env('FACEBOOK_API_ID'), 'client_secret' => env('FACEBOOK_API_SECRET'), 'redirect' => env('FACEBOOK_CALLBACKURL'), ], 'google' => [ 'client_id' => env('GOOGLEPLUS_API_ID'), 'client_secret' => env('GOOGLEPLUS_API_SECRET'), 'redirect' => env('GOOGLEPLUS_CALLBACKURL'), ],
config/services.phpへ直接、client_idやclient_secretを書いても良いのですが、今回は、実際の内容は、.envに設定します。
.envの設定
#### # Social Settings #### # Twitter TWITTER_API_KEY=YOURKEY TWITTER_API_SECRET=YOURSECRET TWITTER_CALLBACKURL=https://yourdomain.com/login/twitter/callback # Facebook FACEBOOK_API_ID=YOURKEY FACEBOOK_API_SECRET=YOURSECRET FACEBOOK_CALLBACKURL=https://yourdomain.com/login/facebook/callback # Google Plus GOOGLEPLUS_API_ID=YOURKEY GOOGLEPLUS_API_SECRET=YOURSECRET GOOGLEPLUS_CALLBACKURL=https://yourdomain.com/login/google/callback
これでソーシャルログインの機能は出来上がりました。
今回は、Twitterの・FaceBook・Googleの例しか示しいませんが、ログインページを表示すると下記のようなページが表示されるはずです。
各SNSのアイコンをクリックすると、登録済みの場合は、ログイン、まだ、メールアドレスが登録されていない場合は、アカウントの登録を求めるページへ遷移するはずです。
この辺りは、LoginControllerのコールバックメソッドを変更することで、一気に会員登録させてしまうことも可能です。
Twitterの場合は、アプリ作成の時点で、メールアドレスの取得をすることが出来たりするので(おそらく他のSNSもそうだと思います)、その方法もありだと思います。
今回の場合は、下記のように名前とメールアドレスを取得し、パスワードを設定するように促し、次回以降は、メールアドレスでもソーシャルログインでもどちらでもできるようにしています。
Socialite Providersプロジェクト
Socialiteでは使えるSNSが限られていますが、デフォルトのSocialiteで使用できないSNSでのソーシャルログインを実装したいということもあると思います。
Socialite Providersはたくさんの非公式プロバイダーをSocialiteで使えるようにするプロジェクトで、コミュニティで開発が進められています。プロバイダーは独立したパッケージとしてComposer経由でインストールできます。
SpotifyやInstagramのソーシャルログインも簡単に実装することが可能です。
まとめ
今回、ユーザーログイン、管理者ログイン、ソーシャルログインの方法を紹介しました。
一回、それぞれのログインの仕組みを作ってしまったものを持っていると、それを元に色々なサービスを作ることができると思います。
Laravel5系で何かサービスを作りたいと思っている方は、ひとまずログイン周りだけ作ってしまうというのはどうでしょうか。