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

最近LaravelのSocialiteを使ってTwitterログインをWebアプリに実装するところを試していたのですが、うまく動作したので今回は実装方法をご紹介したいと思います。

まずはTwitter APIの取得が必要になるので、Twitterの開発者ページから申請・APIトークン取得を行います。

APIトークンが発行されたら、コールバックURLも設定しておきます。

ここまで出来たら、Laravel側にTwitterログインを実装していきます。

ここでは、下記3点を前提として進めていきます。

・すでにインターネット経由でアクセスできるサーバーにLaravelが動作可能な状態でインストールされている
・DBにユーザー情報を登録するテーブルが追加済み
・ユーザー情報テーブルのmodelが作成済み

Laravel自体のセットアップ方法は下記を参照してください。

https://techacademy.jp/magazine/11521

まず、Laravelのプロジェクト内へ移動した後、composerでSNS認証プラグインのsocialiteをインストールしておきます。

cd /path/to/laravel #Laravelがインストールされているプロジェクト(フォルダ)のパス

composer require laravel/socialite #socialiteのインストール

これでSNS認証プラグインがLaravelにインストールされました。

次にコントローラーにログイン時の処理を記述していきます。

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

例として下記に上記のサイトを参考に自分が書いたソースを掲載します。

<?php

//ネームスペース設定
namespace App\Http\Controllers\Auth;

// プラグインのインポート
use App\Http\Controllers\Controller;
use App\Model\User; //ユーザー情報テーブルEloquentモデル
use \File; //ファイル操作プラグイン
use Illuminate\Support\Facades\Auth; 
use Illuminate\Support\Facades\Storage; //Storageプラグイン(ファイルの保存などに必要)
use Laravel\Socialite\Facades\Socialite; //先程インストールしたSNS認証プラグイン

class TwitterController extends Controller
{

    // ログイン
    public function redirectToProvider()
    {
        return Socialite::driver('twitter')->redirect();
    }

    // コールバック
    public function handleProviderCallback()
    {
        try {
            $twitterUser = Socialite::driver('twitter')->user();
        } catch (Exception $e) {
            return redirect('auth/twitter');
        }

        // Webアプリへのログイン処理
        // TwitterのidがすでにWebアプリのDB上に登録されていないかを確認
        $user = User::where('user_id', $twitterUser->id)->first();
        //オリジナルサイズのプロフィール画像取得
        $original_url = str_replace("_normal.", ".", $twitterUser->user['profile_image_url_https']);
        // 新しいプロフィール画像を保存
        $prof_icon_path = $this->_putProfileImage($twitterUser->id, $original_url);

        // 新規ユーザーの場合
        if (!$user) {
            User::create([ //TwitterAPIから取得したユーザー情報をDBに突っ込む
                // 配列のキー: DBテーブルのカラム名
                'user_id' => $twitterUser->id, //TwitterID(同一アカウントであれば変更不可のもの。アカウントの同定に使用)
                'screen_name' => $twitterUser->nickname, //TwitterログインID
                'view_name' => $twitterUser->name, //表示上のTwitterユーザー名
                'description' => $twitterUser->user['description'], //プロフィール
                'user_icon_path' => $prof_icon_path, //先程保存したアイコン画像のパス
            ]);
            // 突っ込んだユーザー情報をDBから再取得(Webアプリ側のログイン処理に必要)
            $user = User::where('user_id', $twitterUser->id)->first();
        } else {
            // ユーザー情報がすでにある場合
            // ID以外の新しいユーザー情報を登録
            // 左辺の書式: $モデル名->DBテーブルのカラム名
            $user->screen_name = $twitterUser->nickname; //TwitterログインID
            $user->view_name = $twitterUser->name; //表示上のTwitterユーザー名
            $user->description = $twitterUser->user['description']; //プロフィール
            $user->user_icon_path = $prof_icon_path; //先程保存したアイコン画像のパス
            $user->save(); //DB更新
        }
         //共通処理
         Auth::login($user); //Webアプリにログイン
         return redirect('/'); //TOPへリダイレクト
    }

    // ログアウト
    public function logout(Request $request)
    {
        // ログアウト処理
        Auth::logout();
        return redirect('/');
    }

    private function _putProfileImage($userid, $photo_url)
    {
        $img = file_get_contents($photo_url); //プロフィール画像のバイナリをTwitterから取得
        $img_ext = $this->_getImageTypes($photo_url); //取得したバイナリから拡張子を推定

        //画像を保存
        $prof_icon_path = 'proficons/' . $userid . '.' . $img_ext; //保存パス定義(proficons/ユーザーid.拡張子)
        if (File::exists($prof_icon_path)) { //すでに指定パスに画像がある場合
            Storage::delete($prof_icon_path); //上書きできないため一旦消す
        }
        Storage::disk('local')->put($prof_icon_path, $img); //Twitterから取得した画像をサーバーに保存
        return $prof_icon_path; //保存パスを返す
    }

    //画像バイナリから拡張子を推定する関数(mimetypeを使用)
    private function _getImageTypes($photo_url)
    {
        //getimagesize関数で画像情報を取得する
        list($img_width, $img_height, $mime_type, $attr) = getimagesize($photo_url);
//list関数の第3引数にはgetimagesize関数で取得した画像のMIMEタイプが格納されているので条件分岐で拡張子を決定する
        switch ($mime_type) {
            //jpegの場合
            case IMAGETYPE_JPEG:
                //拡張子の設定
                $img_extension = "jpg";
                break;
            //pngの場合
            case IMAGETYPE_PNG:
                //拡張子の設定
                $img_extension = "png";
                break;
            //gifの場合
            case IMAGETYPE_GIF:
                //拡張子の設定
                $img_extension = "gif";
                break;
        }
        // 拡張子の出力
        return $img_extension;
    }
}

次にルートを指定します。

// TwitterログインURL
Route::get('login/twitter', 'Auth\TwitterController@redirectToProvider'); //標準ログインにそろえて
// TwitterコールバックURL
Route::get('auth/twitter/callback', 'Auth\TwitterController@handleProviderCallback');
// TwitterログアウトURL
Route::get('auth/twitter/logout', 'Auth\TwitterController@logout');

ログインURLを”login/twitter”にしてあるのは、単純にLaravelのログインURLとそろえたかっただけで、”auth/twitter/login”としても大丈夫です。

2番目の”TwitterコールバックURL”の部分については、Twitterの管理画面側で指定したURLと一致している必要があります。

それでは実際にTwitterログインのテストを行ってみます。

上記の例であれば、”https://ドメイン名/login/twitter”にアクセスします。

するの下記のような見慣れた画面にリダイレクトします。

あとはここでTwitterへログインする際の情報を入力すれば、先程指定したCallbackURLに対してログインしたユーザーの登録情報が返却されます。

そこから入手できる情報から、自サイトで会員登録に必要な情報を抜き出してDBなどに保存する処理を記述すれば、Twitterログイン機能の完成です。

あとはTwitterログインボタンをログイン画面などに設置して、TwitterログインのURLに誘導すればOKです。

なお、上記の例ではサービスの会員管理とSNSログインの会員管理を同じテーブルで扱っていますが、実際に運用する場合はどこかでTwitterのIDと自サイトのIDが重複して困ったことになる可能性があるので、TwitterIDは別テーブルで管理して、自サイトの独自IDと紐づけておくほうが安心です。

Laravel上でSNSログインを実装したい方の参考になれば幸いです。

>株式会社シーポイントラボ

株式会社シーポイントラボ

TEL:053-543-9889
営業時間:9:00~18:00(月〜金)
住所:〒432-8003
   静岡県浜松市中央区和地山3-1-7
   浜松イノベーションキューブ 315
※ご来社の際はインターホンで「316」をお呼びください

CTR IMG