Laravel5.4でTwitterログインの実装

# 概要

Laravel5.4からSocialiteというライブラリを用いてTwitterのソーシャルログインを実装します。

Socialiteが優秀なので簡単に実装出来ます。

本記事はLaravelを初めて使う人にも読めるようにしています。

始めに言っておくとControllerの分け方とかはベストプラクティスではないです。

http://goodheads.io/2015/08/24/using-twitter-authentication-for-login-in-laravel-5/

上記の記事を大きく参考にしています。

差分としては、

- 日本語であること
- Laravel5.4に対応していること
- サンプルコードをGitHubにアップしておいたこと

です。

Laravel5.4ではデフォルトからnpm installでVue.jsが入るようになり、とても便利になりました。


# まず初めに試してみる

https://github.com/solt9029/TwitterLoginLaravelTutorial

上記のリポジトリにサンプルコードが入っています。

READMEに手順を書いたので、その通りに行うと、Twitterログインが実装できているかと思います。

Dockerの使い方やTwitterAPIの使い方は省略させて頂きます。申し訳ありません。


# クリーンな状態からの手順解説

まず初めにLaravelをインストールします。

```
composer create-project --prefer-dist laravel/laravel TwitterLoginLaravelTutorial 5.4.23
```

Socialiteというライブラリをインストールしちゃいます。

```
composer require laravel/socialite
```

config/app.phpのprovidersという配列に対して以下の一行を付け加えます。

```php
Laravel\Socialite\SocialiteServiceProvider::class
```

config/app.phpのaliasesという配列に対して以下の一行を付け加えます。

```php
'Socialite' => Laravel\Socialite\Facades\Socialite::class
```

config/services.phpに以下のコードを足します。

```php 
'twitter' => [
    'client_id' => env('TWITTER_CLIENT_ID'),
    'client_secret' => env('TWITTER_CLIENT_SECRET'),
    'redirect' => env('CALLBACK_URL')
]
```

その後、.envを編集します。

CALLBACK_URLは適宜修正してください。

基本的にはDockerMachineのIPアドレスなどを確認してください。

```
TWITTER_CLIENT_ID=(あなたのTwitterクライアントID)
TWITTER_CLIENT_SECRET=(あなたのTwitterクライアントIDシークレット)
CALLBACK_URL=http://docker.app:8005/auth/twitter/callback(Docker for Windowsとかを使用しているんだったらlocalhost)
```

routes/web.phpに対して以下のように書き直してください。

ルーティングを行います。

```php
Route::get('/', array('as' => 'login', 'uses' => function(){
    return view('welcome');
}));
Route::get('auth/twitter', 'Auth\SocialAuthController@redirectToProvider');
Route::get('auth/twitter/callback', 'Auth\SocialAuthController@handleProviderCallback');
Route::get('auth/twitter/logout', 'Auth\SocialAuthController@logout');
Route::get('home', array('as' => 'home', 'uses' => function(){
    if(!Auth::check()){
        return redirect()->route("login");
    }
    return view('home');
}));
```

app/Http/Controllers/Auth/SocialAuthController.phpというファイルを作成し、以下のように記述してください。

```php
<?php
namespace App\Http\Controllers\Auth;
use App\User;
use Auth;
use Socialite;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
class SocialAuthController extends Controller
{
    use AuthenticatesUsers;
    protected $redirectTo = '/home';
    public function redirectToProvider()
    {
        return Socialite::driver('twitter')->redirect();
    }
    public function handleProviderCallback()
    {
        try {
            $user = Socialite::driver('twitter')->user();
        } catch (Exception $e) {
            return redirect('auth/twitter');
        }
 
        $authUser = $this->findOrCreateUser($user);
 
        Auth::login($authUser, true);
 
        return redirect()->route('home');
    }
    private function findOrCreateUser($twitterUser)
    {
        $authUser = User::where('twitter_id', $twitterUser->id)->first();
 
        if ($authUser){
            return $authUser;
        }
 
        return User::create([
            'name' => $twitterUser->name,
            'handle' => $twitterUser->nickname,
            'twitter_id' => $twitterUser->id,
            'avatar' => $twitterUser->avatar_original
        ]);
    }
    public function logout()
    {
        Auth::logout();
        return redirect()->route('login');
    }
    public function __construct()
    {
        $this->middleware('guest')->except('logout');
    }
}
```

あとはデータベースも作らなくてはなりません。

データベースの作成にはマイグレーションというものを使います。

database/migrations/2014_10_12_000000_create_users_table.phpを書き換えます。

```php
$table->increments('id');
$table->string('name');
$table->string('handle');
$table->string("twitter_id");
$table->string("avatar");
$table->rememberToken();
$table->timestamps();
```

あとはviewだけです！

resources/views/home.blade.phpを以下のように書き換えます。

```html
<body>
    <div class="container">
        <div class="content">
        <div class="title">Laravel 5</div>
            You are logged in
        <div>
            <h4>Your name is {{ Auth::user()->name }} </h4>
            <h4>Your twitter handle is {{ Auth::user()->handle }} </h4>
            <img src="{{ Auth::user()->avatar }}" height="200" width="200" />
        </div>
        <div>
            <a href="auth/twitter/logout" role="button">Logout</a>
        </div>
    </div>
</body>
```

resources/views/welcome.blade.phpを以下のようにします！

```html
<body>
    <div class="container">
        <div class="content">
        <div class="title">Laravel 5</div>

        <a class="btn btn-info" href="auth/twitter" role="button">Login with Twitter</a>
        </div>
    </div>
</body>
```

最後にマイグレーションを行います。

ここら辺は私のサンプルコードの中にあるdockerを使って頂いても良いですし（超雑ですが）、Homesteadを使っても何でもいいと思います。(Homesteadの方が良いですw)

```
php artisan migrate
```

これで完成です！