LoginSignup
30
29

More than 5 years have passed since last update.

laravel5.5でemeil認証+ソーシャルアカウント認証

Last updated at Posted at 2018-02-07

前提

見た目を作ることしかわからない自分が勉強がてらやってみてログってる中身です。
これをやったらマズイのよ、という点がありましたらご指摘いただけると幸いですmm

やること

・laravelデフォルト認証(email+password)とソーシャルアカウント認証、両方を可能にする
・デフォルトなページ遷移(メール認証がAPIだったりSPAでは無い)
・データベースは1テーブルに収める
イメージ

id username email password facebook_id facebook_name 以下略SNS_id 以下略SNS_name

・以下はFacebook&Twitterを認証に追加で記載

環境

laravel5.5 インストール済み
SQlite3を利用

参考

(WPJ)面倒なソーシャルログインをLaravelでサクッと実装!Socialiteが便利だ:https://www.webprofessional.jp/easily-add-social-logins-to-your-app-with-socialite/

https://readouble.com/laravel/5.5/ja/authentication.html
https://readouble.com/laravel/5.5/ja/socialite.html

事前準備

基本設定

データベースをsqliteに設定

ユーザー認証機能を有効化

$ php artisan make:auth //→認証用のビュー、コントローラーをインストール
$ php artisan migrate //→デフォルトで作成されているuser関連のmigrationファイルのマイグレート

パッケージの追加

Socialite:laravel公式パッケージ。

現在、Facebook、Twitter、LinkedIn、Google、GitHub、Bitbucketによる認証をサポートしています。

$ composer require laravel/socialite
config/app.php
'providers' => [
    
    Laravel\Socialite\SocialiteServiceProvider::class, //追記
],
'aliases' => [
    
    'Socialite' => Laravel\Socialite\Facades\Socialite::class, //追記
],

※ソーシャルプロバイダープロジェクトを活用することで、もっと様々なサービスの連携も可能
https://socialiteproviders.github.io/

連携サービスの認証情報

やり方省略

・facebook
https://developers.facebook.com/
・twitter
https://apps.twitter.com/

認証情報をアプリ側に持たせる

configファイルで環境設定を呼び出す記述追加

config/service.php
return [
~~ 以下追記
    'facebook' => [
        'client_id' => env('FACEBOOK_CLIENT_ID'),
        'client_secret' => env('FACEBOOK_CLIENT_SECRET'),
        'redirect' => env('FACEBOOK_CLIENT_CALLBACK'),
    ],

    'twitter' => [
        'client_id' => env('TWITTER_CLIENT_KEY'),
        'client_secret' => env('TWITTER_CLIENT_SECRET'),
        'redirect' => env('TWITTER_CLIENT_CALLBACK'),
    ],
]
.env
以下追記(&自分環境に応じて書き換え
#facebook
FACEBOOK_CLIENT_ID=FACEBOOKのClientID
FACEBOOK_CLIENT_SECRET=FACEBOOKのClientSecret
FACEBOOK_CLIENT_CALLBACK=FACEBOOKのCallBackURL

#twitter
TWITTER_CLIENT_KEY=TWITTERのconsumerkey
TWITTER_CLIENT_SECRET=TWITTERのconsumersecret
TWITTER_CLIENT_CALLBACK=TWITTERのCallBackURL

ルーティングの設定

routes/web.php
<?php

Route::get('login/{provider}', 'Auth\SocialAccountController@redirectToProvider');
Route::get('login/{provider}/callback', 'Auth\SocialAccountController@handleProviderCallback');

・各サービスに向かうやつと、帰ってきた(コールバック)時用の2つを記載。
・どの認証サービスでも同じく使えるように、ルートパラメーター{provider}で指定。

ビューの設定

ユーザー認証のビューのファイルが自動でできているので、とりあえず、↓を追記。
(あとで整える!…は省略。)

resouces/views/auth/login.blade.php
<a href="auth/login/facebook">Sign in with Facebook</a>
<a href="auth/login/twitter">Sign in with Twitter</a>

ルーティングに設定したURLを元に記載。

ルーティング: login/{provider}
↓
ビュー: auth/login/プロバイダー(サービス)名

…なんかauth/が必要やった。

データベースの設定

(↓※2018.3.4追記)データベース修正用に[doctrine/dbal]パッケージインストール

$ composer require doctrine/dbal
$ php artisan make:migration prepare_users_table --table users

→タイムスタンプ_prepare_users_table.phpが作成される

database/migrations/タイムスタンプ_prepare_users_table.php
public function up()
{
    Schema::table('users', function (Blueprint $table) {
        $table->string('email')->nullable()->change();
        $table->string('password')->nullable()->change();
        $table->string('avatar')->nullable();
        $table->string('facebook_id')->unique()->nullable();          
        $table->string('facebook_name')->nullable();
        $table->string('twitter_id')->unique()->nullable();          
        $table->string('twitter_name')->nullable();
    });
}

【抜粋】

デフォルトで入っているカラムを変更。
//SNS経由での登録はパスワードがいらなかったり、emailがなかったりするので、nullableに変更
        $table->string('email')->nullable()->change();
        $table->string('password')->nullable()->change();
カラム追加
//ユーザーサムネイル設定できるように追加
        $table->string('avatar')->nullable();
SNSアカウントを保存するカラム追加
//それぞれのSNSコラムになんか入ってたらそのSNS認証使える、みたいにできないかと…な、こんな設定。
        $table->string('facebook_id')->unique()->nullable();          
        $table->string('facebook_name')->nullable();
        $table->string('twitter_id')->unique()->nullable();          
        $table->string('twitter_name')->nullable();

設定したら、マイグレート

$ php artisan migrate

コントロラーの設定

コントローラファイル作成

routes/web.php(設定済)
Route::get('login/{provider}', 'Auth\SocialAccountController@redirectToProvider');
Route::get('login/{provider}/callback', 'Auth\SocialAccountController@handleProviderCallback');

↑で設定したように、「SocialAccountController」コントローラを作成し、
コントローラアクション
・redirectToProvider
・handleProviderCallback
を設定できるようにする

$ php artisan make:controller 'Auth\SocialAccountController'

→app/Http/Contorollers/Auth/SocialAccountController.phpが作成される

※認証系コントローラを同じディレクトリにまとめるため、/auth内に作成。

(↓※2018.3.4追記)socialite呼びだし

SocialAccountController.php
namespace App\Http\Controllers\Auth;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

use Socialite; //⇦追記

class SocialAccountController extends Controller

自分のサービス→認証サービス

各認証サービスへリダイレクト。

SocialAccountController.php
class SocialAccountController extends Controller
{
    public function redirectToProvider($provider) {
        return Socialite::driver($provider)->redirect();
    }
}

認証サービス→自分のサービス

SocialAccountController.php
class SocialAccountController extends Controller
{
  public function handleProviderCallback($provider) {
    try {
      $providerUser = Socialite::driver($provider)->user();

      $user = DB::table('users')->where('email', $providerUser->getEmail())->first();

      if( is_null($user) ){

        if( is_null($providerUser->getNickname()) ){
          $providerUserNickName = $providerUser->getName();
        }else{
          $providerUserNickName = $providerUser->getNickname();
        }

        $userd = User::create([
          'name' => $providerUserNickName,
          'email' => $providerUser->getEmail(),
        ]);

      }else{
        $userd = User::find( $user->id );
      }

      switch ($provider) {
        case "facebook":
          if( is_null($userd->facebbook_id) ){
            $userd->facebook_id = $providerUser->getId();
            if( is_null($providerUser->getNickname()) ){
              $userd->facebook_name = $providerUser->getName();
            }else{
              $userd->facebook_name =$providerUser->getNickname();
            }
          }
          break;
        case "twitter":
          if( is_null($userd->twitter_id) ){
            $userd->twitter_id = $providerUser->getId();
            if( is_null($providerUser->getNickname()) ){
              $userd->twitter_name = $providerUser->getName();
            }else{
              $userd->twitter_name = $providerUser->getNickname();
            }
          }
          break;
      }
      $userd->save();

      auth()->login($userd, true);
      return redirect()->to('/home');

    } catch (\Exception $e) {
      return redirect("/");
    }

  }
}

取得した連携SNSアカウントのmailがすでに登録されているユーザーのemailと同じなら、そのユーザーのSNSカラムに追記できるようになりました。
同じemailが無かったら新しいアカウントです。

ところが…

twitterはデフォルトではemail情報が取れない

参照:https://qiita.com/wheatandcat/items/fe66c7ee2521a6966505

取得するには利用規約とプライバシーポリシーを準備する必要があるようです。

30
29
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
30
29