Help us understand the problem. What is going on with this article?

Laravelのログイン機能にSNS認証を追加する(socialite)

socialiteでSNSログインを実装

Laravelで、SNSのアカウントを使ったログインの実装をした時のメモです。

socialiteとは

soscialiteとは、Laravelで簡単にOAuth(SNS認証)を可能にするパッケージツールです。

はじめに、composerを使ってsocialiteをインストールします。

$ composer require laravel/socialite

コンフィグレーション

Socialiteを使用する前に、アプリケーションが使用するOAuthサービスの認証情報を設定します。

services.phpの設定

認証情報を必要とする各プロバイダーの設定を行います。

config/services.php
return [

    'github' => [
        'client_id' => env('GITHUB_CLIENT_ID'),
        'client_secret' => env('GITHUB_CLIENT_SECRET'),
        'redirect' => env('APP_URL') . '/login/github/callback',
    ],

    'google' => [
        'client_id' => env('GOOGLE_CLIENT_ID'),
        'client_secret' => env('GOOGLE_CLIENT_SECRET'),
        'redirect' => env('APP_URL') . '/login/google/callback',
    ],

    'facebook' => [
        'client_id' =>  env('FACEBOOK_APP_ID'),
        'client_secret' => env('FACEBOOK_APP_SECRET'),
        'redirect' =>  env('APP_URL') . '/login/facebook/callback',
    ],
];

app.phpでsocialiteの設定を行います。

config/app.php
    'providers' => [
        // 追加
        Laravel\Socialite\SocialiteServiceProvider::class,
    ],

    'aliases' => [
        // 追加
        'Socialite' => Laravel\Socialite\Facades\Socialite::class,
    ],

ルーティング

次に、ユーザーを認証する準備ができました。2つのルートが必要になります。

1つはユーザをOAuthプロバイダにリダイレクトするためのもので、もう1つは認証後にプロバイダからのコールバックを受け取るためのものです。

Socialite ファサードを使って Socialite にアクセスします。

Controllerの設定

設定した情報からSNS認証ログインを実装します。

App/Http/Controllers/Auth/LoginController.php
<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;

use Hash;
use Auth;
use Socialite;
use App\User;

class LoginController extends Controller
{
    use AuthenticatesUsers;

    protected $redirectTo = '/home';

    public function __construct()
    {
        $this->middleware('guest')->except('logout');
    }

    public function redirectToProvider($social)
    {
        return Socialite::driver($social)->redirect();
    }

    public function handleProviderCallback($social)
    {

        $socialUser = Socialite::driver($social)->user();

        // 第一引数の配列内の条件に合致するものがなければ、第二引数の配列内のkeyとvalueでDBへ作成
        $user = User::firstOrCreate(
            ['provider_id' => $socialUser->getId()],
            ['name' => $socialUser->getName(),
            'provider' => $social,
            'provider_id' => $socialUser->getId(),
            ]
        );

        Auth::login($user, true);
        return redirect('/home');
    }

}

Userクラスの設定

ログイン時に新規作成するUserテーブルは、挿入できるように追記しておきます。

App/User.php
class User extends Authenticatable
{
    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password', 'provider_id', 'provider', // カラムを追記
    ];

マイグレーションの設定

emailやpasswordがなくてもユーザー登録ができるように、nullable()を追記します。

database/migrations/2014_10_12_000000_create_users_table.php
class CreateUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('provider')->nullable();
            $table->string('provider_id')->nullable();
            $table->unique(['provider', 'provider_id']);
            $table->string('name');
            $table->string('email')->unique()->nullable();
            $table->string('password')->nullable();
            $table->rememberToken();
            $table->timestamps();
        });
    }

web.phpの設定

web.phpにてログイン画面でボタンをクリックしたときのリンクを設定します。

たとえば、シンプルにGitHubだけで実装する場合には下記のようになります。

web.php
Auth::routes();
Route::get('/home', 'HomeController@index')->name('home');

Route::get('login/github', 'Auth\LoginController@redirectToProvider');
Route::get('login/github/callback', 'Auth\LoginController@handleProviderCallback');

複数のプロバイダーで認証を実装する場合は、引数に変数を用いて変換します。

web.php
// SNS認証 ログインボタンのリンク
Route::get('/login/{social}', 'Auth\LoginController@redirectToProvider')->where('social', 'github|google|facebook');
// コールバック用
Route::get('/login/{social}/callback', 'Auth\LoginController@handleProviderCallback')->where('social', 'github|google|facebook');

Viewの設定

ログイン画面のテンプレートに追記します。
(※下記の例では、Bootstrapを使用しています。)

login.blade.php
    <div class="form-group row mt-5">
        <label for="name" class="col-sm-4 col-form-label text-md-right">SNSログイン</label>
        <div class="col-md-6">
            <a href="{{ url('login/google')}}" class="btn btn-danger"><i class="fa fa-google"> Google</i></a>
            <a href="{{ url('login/facebook')}}" class="btn btn-primary"><i class="fa fa-facebook"> Facebook</i></a>
            <a href="{{ url('login/github')}}" class="btn btn-secondary"><i class="fa fa-github"> GitHub</i></a>
        </div>
    </div>

デフォルトのログインテンプレートに追記すると、このように表示されます。
スクリーンショット 0032-05-23 8.16.02.png

.envの設定

.envファイルにて各SNSで取得したクライアントIDとシークレットIDを設定。

GITHUB_CLIENT_ID=xxxxxxxxxxxxxxxxxxxx
GITHUB_CLIENT_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

GOOGLE_CLIENT_ID=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=xxxxxxxxxxxxxxxxxxxxxxxx

FACEBOOK_APP_ID=xxxxxxxxxxxxxxx
FACEBOOK_APP_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

参考

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした