概要
Laravel5.4からSocialiteというライブラリを用いてTwitterのソーシャルログインを実装します。
Socialiteが優秀なので簡単に実装出来ます。
本記事はLaravelを初めて使う人にも読めるようにしています。
始めに言っておくとControllerの分け方とかはベストプラクティスではないです。
上記の記事を大きく参考にしています。
差分としては、
- 日本語であること
- Laravel5.4に対応していること
- サンプルコードをGitHubにアップしておいたこと
です。
Laravel5.4ではデフォルトからnpm installでVue.jsが入るようになり、とても便利になりました。
まず初めに試してみる
上記のリポジトリにサンプルコードが入っています。
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という配列に対して以下の一行を付け加えます。
Laravel\Socialite\SocialiteServiceProvider::class
config/app.phpのaliasesという配列に対して以下の一行を付け加えます。
'Socialite' => Laravel\Socialite\Facades\Socialite::class
config/services.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に対して以下のように書き直してください。
ルーティングを行います。
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
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を書き換えます。
$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を以下のように書き換えます。
<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を以下のようにします!
<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
これで完成です!