LaravelでSocialiteを使ってソーシャルログインを実装する

シェアする

フリーランスエンジニアの収入例を見てみる→フリーエンジニア高額案件多数【ギークスジョブ】

Laravel5ソーシャルログインの機能を実装することがあるかと思います。

今回の記事では、Laravel5でソーシャルログインの機能を実装する方法について紹介します。
Laravel5の環境構築については、下記のページを参照ください。

LAMP環境やLNMP環境にPHPフレームワーク Laravel5.5・Laravel5.6をインストールする方法について紹介しています。 Laravel5.5・Laravel5.6をインストールする際の参考にしてください。

今回の記事は、下記の記事を作成時点のアプリケーションに作成しているので、Laravel5の知識がない方は、こちらも合わせて読んだ方がわかりやすいかもしれません。また、この記事は、laravel authコマンドを使用して認証システムを実装していることが前提です。こちらの記事に方法が書かれているので、参照してください。

Laravel5.5でログイン機能を実装して見ました。Laravel5では、ログイン機能はartisanコマンド1つで実装することが出来ます。Laravel5でログイン機能を実装しようと考えている方は、参考にしてください。
Laravel5でマルチ認証(マルチログイン機能)を実装するする方法について紹介しています。Laravel5.5でマルチログインを実装しようとしている人は、参考にしてください。

環境

  • 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認証を実装する事ができます。

=>laravel/socialite

・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>

Social buttonsのCSSの読み込み

/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のソーシャルログインも簡単に実装することが可能です。

Socialite Providers

まとめ

今回、ユーザーログイン、管理者ログイン、ソーシャルログインの方法を紹介しました。
一回、それぞれのログインの仕組みを作ってしまったものを持っていると、それを元に色々なサービスを作ることができると思います。

Laravel5系で何かサービスを作りたいと思っている方は、ひとまずログイン周りだけ作ってしまうというのはどうでしょうか。