【Laravel 7.x】Twitterログインしてみよう

Pocket

目的

自作サービスで実装したので、同じようにTwitterアカウントでログインさせたい時に活用出来るように解説します。

 

事前準備

・Twitter Developer登録

・Laravel 7.16.1

・Socialiteのインストール、設定

 

参考サイト

LaravelでTwitterログインを実装する

【2020年Mac】ゼロからのlaravel環境構築

LaravelでTwitterログインを実装する方法(2020年9月現在)

 

コード実装

ルーティングの設定

//ログイン画面遷移時のURL
Route::get('/twitter', 'Auth\TwitterLoginController@redirectToProvider')->name('login');

//ユーザーが認証後に遷移するURL
//TwitterDeveloperのCallbackURLと同じにする
Route::get('/auth/twitter/callback', 'Auth\TwitterLoginController@handleProviderCallback');

//ログアウト時のURL
Route::get('/logout', 'Auth\TwitterLogoutController@getLogout')->name('logout');

 

コントローラーの設定

app/Http/Controllers/AuthにTwitterLoginController.phpとTwitterLogoutController.phpを作成します。

DBへのインサートは適宜変更してください。

<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Socialite;
use App\User;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Auth;
use Exception;

class TwitterLoginController extends Controller
{
    //ユーザー認証画面の遷移する
    public function redirectToProvider() {
        return Socialite::driver('twitter')->redirect();
    }

    //ユーザーが認証後に処理される
    public function handleProviderCallback() {
        
        //try-catchで認証後にエラーが出た際はログインさせずにtopページに戻す
        try {
            //認証したユーザーデータを取得する
            $twitter_account = Socialite::driver('twitter')->user();
            $twitter_id = $twitter_account->id;
            
            //過去にサービスを利用したユーザーかどうかを調べる
            $db_user = User::where('twitter_id', $twitter_id)->first();
            
            
            //新規ユーザーの場合は新しくDBに入れる
            if(is_null($db_user)) {
                // DBインサート
                $new_registered_user = new User([
                    'twitter_id' => $twitter_account->id,
                    'user_name' => $twitter_account->name,
                    'screen_name' => $twitter_account->nickname,
                    'profile_image_url' => $twitter_account->user['profile_image_url_https'],
                    'oauth_token' => $twitter_account->token,
                    'oauth_token_secret' => $twitter_account->tokenSecret,
                ]);
                
                //DBの保存
                $new_registered_user->save();
                
                //サービスへのログイン処理
                Auth::login($new_registered_user);
                
                //ログイン後のページに遷移させる
                return redirect('/calendar');
            };
            
            //登録済みの場合はユーザー情報を更新
            User::where('twitter_id',$twitter_id)->update([
                'user_name' => $twitter_account->name,
                'profile_image_url' => $twitter_account->user['profile_image_url_https'],
                'oauth_token' => $twitter_account->token,
                'oauth_token_secret' => $twitter_account->tokenSecret,
                'delete_flg' => false,
            ]);
            
            //サービスへのログイン処理
            Auth::login($db_user);
            
            //ログイン後のページに遷移させる
            return redirect('/calendar');

        //エラー時の処理(DBサーバーが落ちてたり、ユーザーのデータが取得できなかった時)
        } catch (Exception $e) {
            //ログファイルにデータを残す
            Log::info($e->getMessage());
            
            //トップ画面に戻ってメッセージを表示させる
            session()->flash('flash_message', 'Twitterアカウント読み取りに失敗しました。');
            return redirect('/');
        }
    }
}

 

<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;

class TwitterLogoutController extends Controller
{
    public function getLogout() {
        //ログアウト処理
        Auth::logout();
        return redirect()->route('top');
    }
}

 

モデルの設定

参考までに今回導入時のモデルも記載します。

<?php

namespace App;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class User extends Authenticatable
{
    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'twitter_id', 'user_name', 'screen_name','profile_image_url','oauth_token','oauth_token_secret',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'remember_token',
    ];

    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'twitter_id' => 'unsignedBigInteger',
    ];
}

 

viewsファイルへの書き方

今回はルーティング設定時に名前を付けたので以下で遷移できます。

<a class="" href="{{ route('login') }}">

 

最後に

Twitterの情報だけで完結できるサービスだと尚更使い勝手良さようですね。

他のアカウント(github)でも実装できるようなので試してみたいと思います。

最後まで読んで頂きありがとうございました!