Theme
SD MILIEU

2018-9-17

[Laravel] Twitter認証を使用してログインするまで

Twitter 認証をしてログインするまでの手順が難しくはないがやることが結構あったので覚書

手順

  • socialite のインストール
  • config/service.php及び.envの更新
  • LoginController の作成
  • users テーブル、User モデルの作成
  • ユーザー情報登録・ログイン処理
  • 認証していないと見れないページの作成

socialite のインストール

composer require laravel/socialite

config/service.php及び.envの更新

まず、config/service.phpに TwitterApp の Token 情報を記述。

'twitter' => [
    'client_id' => env('TWITTER_CLIENT_ID'),
    'client_secret' => env('TWITTER_CLIENT_SECRET'),
    'redirect' => env('TWITTER_CALLBACK_URL'),
],

それに伴い、.env(.env.example)も更新しておく。

TWITTER_CLIENT_ID=~
TWITTER_CLIENT_SECRET=~
TWITTER_CALLBACK_URL=~

LoginController の作成

LoginController を生成

php artisan make:controller LoginController

LoginController はひとまず次のように記述しておきます。

<?php

namespace App\Http\Controllers;

use Laravel\Socialite\Facades\Socialite;

class LoginController extends Controller
{
    public function login()
    {
        return Socialite::driver("twitter")->redirect();
    }

    public function callback()
    {
        $user = Socialite::driver("twitter")->user();

        var_dump($user);
    }

    public function logout()
    {
        Auth::logout();

        return redirect()->route("home");
    }
}

routes/web.phpに認証系のルーティングを追加すると同時に、トップページにhomeと名前をつけておく。

Route::get('/', function () {
    return view('welcome');
})->name("home"); //このname("home")を追加

Route::get("auth/login", "LoginController@login")->name("login");
Route::get("auth/callback", "LoginController@callback");
Route::get("auth/logout", "LoginController@logout")->name("logout");

これでauth/loginにアクセスすると Twitter 認証され、auth/callbackにてユーザー情報が表示されます。

users テーブル、User モデルの作成

DB 関係の用意をします。

まず、最初に入っているマイグレーションと User モデルは消しておきます。

消したら、users テーブルを作成するマイグレーションを生成。

php artisan make:migration create_users_table

ファイルの中身は以下のようにしておきます。

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->increments("id");
            $table->string("twitter_id");
            $table->string("twitter_name");
            $table->string("twitter_nickname");
            $table->string("twitter_avatar");
            $table->timestamps();
            $table->rememberToken();

            $table->index("twitter_id");
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('users');
    }
}

マイグレーションを実行

php artisan migrate

次に、User モデルを作成します。

php artisan make:model Models/User

User.php の中身は以下の通り。Auth クラスと関連付けるために Authenticatable を継承します。

<?php

namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    protected $fillable = [ "twitter_id" ];
}

同時に、config/auth.phpprovidersmodelに関して、User のディレクトリが変わったので書き換えます。

'providers' => [
    'users' => [
        'driver' => 'eloquent',
        'model' => App\Models\User::class,
    ],
],

ユーザー情報登録・ログイン処理

LoginController の callback を以下のように書き換えると、ユーザー情報の保存が出来ます。

public function callback()
{
    $twitterUserInfo = Socialite::driver("twitter")->user();

    $user = User::firstOrNew([
        "twitter_id" => $twitterUserInfo->id,
    ]);
    $user->twitter_id = $twitterUserInfo->id;
    $user->twitter_name = $twitterUserInfo->name;
    $user->twitter_nickname = $twitterUserInfo->nickname;
    $user->twitter_avatar = $twitterUserInfo->avatar;
    $user->save();

    Auth::loginUsingId($user->id, true);

    return redirect()->route("home");
}

認証していないと見れないページの作成

例として認証していないと見れない URLposts/~を作成。

まず、PostsController を作成。

php artisan make:controller PostsController

PostsController は以下のように index だけ作成しておきます(あくまでテスト用なので)。

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class PostsController extends Controller
{
    public function index()
    {
        echo "posts index";
    }
}

最後に、web.phpに次の行を追加して完了です。

Route::get("posts", "PostsController@index")->name("posts")->middleware("auth");

これで認証していない状態で/postsにアクセスすると、loginという名前がつけられたルート(今回の場合auth/login)へリダイレクトされます。