Laravel Socialite で簡単ソーシャルログイン

[Laravel Advent Calendar 2014](http://qiita.com/advent-calendar/2014/laravel) の4日目のエントリになります。3日目は @ytake さんの [Laravel5 Testing, use Contracts
](http://qiita.com/ytake/items/eab27f60e756f9a0abcd) でした。とてもよいエントリなので読んでみて下さい。

## Laravel Socialite is 何?
`Laravel Socialite` はソーシャルログインを行うためのパッケージです。オプション扱いなので Laravel インストール時には含まれていませんが、 `Composer` から簡単にインストールすることができます。

最初から用意されているドライバは以下になります。

- twitter
- facebook
- google
- github

後述しますが、独自ドライバを作ることも難しくありません。今回は Github にログインしてみます。

## Laravel Socialite のインストール
`composer.json` を下記のように編集します。1行追加するだけです。今回は `Illuminate/Html` もインストールしてます。

```js:composer.json
{
    "name": "laravel/laravel",
    "description": "The Laravel Framework.",
    "keywords": ["framework", "laravel"],
    "license": "MIT",
    "type": "project",
    "require": {
        "laravel/framework": "~5.0",
        "illuminate/html": "~5.0",  // オプションになったので追加
        "laravel/socialite": "~2.0" // ここを追加
    },
    "require-dev": {
        "phpunit/phpunit": "~4.0",
        "barryvdh/laravel-ide-helper": "~1.0"
    },
    "autoload": {
        "classmap": [
            "database",
            "tests/TestCase.php"
        ],
        "psr-4": {
            "App\\": "app/"
        }
    },
    "scripts": {
        "post-install-cmd": [
            "php artisan clear-compiled",
            "php artisan route:scan",
            "php artisan event:scan",
            "php artisan optimize"
        ],
        "post-update-cmd": [
            "php artisan clear-compiled",
            "php artisan ide-helper:generate",
            "php artisan optimize"
        ],
        "post-create-project-cmd": [
            "php artisan key:generate"
        ]
    },
    "config": {
        "preferred-install": "dist"
    },
    "minimum-stability": "dev"
}

```

そして `config/app.php` に `Laravel Socialite` の `Service Provider` と `Facade` を登録します。

```php:app.php
<?php

return [

    'providers'       => [
        'Laravel\Socialite\SocialiteServiceProvider', // こいつが大事
        'Illuminate\Html\HtmlServiceProvider',        // オプションじゃなくてもええんやで…。
    ],
    'aliases'         => [
        'Socialite' => 'Laravel\Socialite\Facades\Socialite',
    ],
];
```


そしてターミナルから

```sh:command
$ composer update
```

でOK. 


## Github にログインしてみよう
では、実際にやってみましょう。

### アプリケーションの登録

まずは [GitHubの設定からApplicationへ遷移して](https://github.com/settings/applications)「Register New Application」を選択します。

![New_OAuth_Application.png](https://qiita-image-store.s3.amazonaws.com/0/25478/21afe057-1e5b-786d-2558-427001c48195.png)

表示された項目を適当に入力します。大事なのは「Authorization callback URL」です。Github 認証後、ここで入力した URL にリダイレクトされます。入力し終わったら「Register applicaiton」ボタンをクリックします。

![OAuth_Application_Settings1.png](https://qiita-image-store.s3.amazonaws.com/0/25478/29b1df2c-7a67-de79-b3af-4f262c21b7ef.png)

クリック後は右上にモザイク加工してある「Client ID」と「Client Secret」をコピーしてエディタに貼りつけておきましょう。後ほど設定ファイルに記述します。

### 設定ファイルに Client ID と Client Secret を登録
`Laravel Socialite` の設定は `config/services.php` に登録します。

```php:services.php
<?php

return [
    'github'   => [
        'client_id'     => 'xxx',
        'client_secret' => 'xxx',
        'redirect'      => 'http://localhost:8000/github/login',
    ]
];

```

`client_id` と `client_secret` は先ほどコピーしたものを。`redirect` には登録時に入力した `Authorization callback URL` を記述します。

…うーむ。こういった設定値はあまり共有したくないですね。Laravel には Ruby の `dotenv` に似た機能を持っていますので書き換えてみましょう。


```php:services.php
<?php

return [
    'github'   => [
        'client_id'     => getenv('GITHUB_CLIENT_ID'),
        'client_secret' => getenv('GITHUB_CLIENT_SECRET'),
        'redirect'      => 'http://localhost:8000/github/login',
    ]
];

```

そしてプロジェクトのルートに `.env` というファイルを作ります。そして以下のように設定します。

```ini:.env
GITHUB_CLIENT_ID=XXXXXXXXXXX
GITHUB_CLIENT_SECRET=XXXXXXXXXXXXXXXXX
```

`.env` ファイルは環境ごとに異なる設定値やバージョン管理に含めたくない API KEY を設定するためのものです。ここに設定した値は `getenv` 関数を使うことによって取得することができます。

設定はこれでお終いです。実装にとりかかりましょう。

## ソーシャルログイン実装してみる
めっちゃ簡単です。`app/Http/routes.php` にさらっと書けます。

```php:routes.php
<?php

Route::pattern('provider', 'github');

Route::get('/', function()
{
    if (!Auth::check()) {
        // ログイン済でなければリダイレクト
        return 'こんにちは ゲストさん. ' . link_to('github/ahthorize', 'Github でログイン.');
    }
    return 'ようこそ ' . Auth::user()->username . 'さん!';
});

Route::get('{provider}/authorize', function($provider)
{
    // ソーシャルログイン処理
    return \Socialite::with($provider)->redirect();
});

Route::get('{provider}/login', function($provider)
{
    // ユーザー情報取得
    $userData = Socialite::with($provider)->user();
    // ユーザー作成
    $user = User::firstOrCreate([
            'username' => $userData->nickname,
            'email'    => $userData->email,
            'avatar'   => $userData->avatar
    ]);
    Auth::login($user);
    
    return redirect('/');
});
```
非常に簡単です。軽く解説すると

1. `'/'`  にアクセスしてログイン済でなければ `github/authorize` にリダイレクト
2. リダイレクト先で `\Socialite::with($provider)->redirect()` をコール
3. すると設定した `Authorization callback URL` にコールバックされるので `Socialite::with($provider)->user()` でユーザーを取得
4. モデルに保存してログイン処理

という感じになります。手軽に使えて非常によい。

## ドライバの独自実装
<del>今書いています。ごめんなさい。更新したら通知するようにしますのでストックしてくれていいのよ？（ﾁﾗﾁﾗ</del>

書きました。一年越しのリベンジ。

[Laravel Socialite の独自ドライバを実装する](http://localdisk.hatenablog.com/entry/2015/12/03/142656)

明日は @syossan27 さんの「Laravelでいくつかサービス作ってみた話」です。お楽しみに！