Laravel5.2 で LINE 認証を3分で実装する方法 〜 独自ドライバを添えて 〜

ソーシャル連携っていつもどう実装するか悩むところですが、Laravel には Socialite というとても簡単に実装できるライブラリがあるのです。
デフォのままでも Facebook, Twitter などかなりの数のプラットフォームに対応していて、しかもネット上に[山程落ちている](https://socialiteproviders.github.io/)ので困ることがありません。

しかしながら日本のサービスはなかなか見つからない。ということで [こちらの記事](http://qiita.com/zaburo/items/25ebbb3d1b580a0df9f3) をほぼまるパクリして LINE のソーシャルログインを実装しました。
一言でどうやるのかと言うと、プロバイダクラスを自作で作り、登録して使えるようにするだけです。

### OAuth2 のプラットフォームの実装方法

コードや構成は zaburo 氏のコピペです。

```php:app/Socialite/LineManeger.php

<?php

namespace App\Socialite;

use Laravel\Socialite\SocialiteManager;

class LineManager extends SocialiteManager{

    protected function createLineDriver()
    {
        $config = $this->app['config']['services.line'];

        return $this->buildProvider(
            'App\Socialite\LineProvider',$config
        );
    }
}

```

```php:app/Socialite/LineServiceProvider.php

<?php

namespace App\Socialite;

use Laravel\Socialite\SocialiteServiceProvider;

class LineServiceProvider extends SocialiteServiceProvider
{
    public function register()
    {
        $this->app->singleton('Laravel\Socialite\Contracts\Factory',function($app){
            return new LineManager($app);
        });
    }
}

```


```php:LineProvider.php


<?php

namespace App\Socialite;

use Laravel\Socialite\Two\AbstractProvider;
use Laravel\Socialite\Two\ProviderInterface;
use Laravel\Socialite\Two\User;

class LineProvider extends AbstractProvider implements ProviderInterface
{
    protected function getAuthUrl($state)
    {
        return $this->buildAuthUrlFromBase('https://access.line.me/dialog/oauth/weblogin', $state);
    }

    protected function getTokenUrl()
    {
        return 'https://api.line.me/v1/oauth/accessToken';
    }

    public function getAccessToken($code)
    {
        $response = $this->getHttpClient()->post($this->getTokenUrl(), [
            'headers' => [
                'Content-Type' => 'application/x-www-form-urlencoded',
            ],
            'form_params' => [
                'grant_type' => 'authorization_code',
                'code' => $code,
                'redirect_uri' => $this->redirectUrl,
                'client_id' => $this->clientId,
                'client_secret' => $this->clientSecret
            ],
        ]);
        return $this->parseAccessToken($response->getBody());
    }

    protected function getUserByToken($token)
    {
        $response = $this->getHttpClient()->get('https://api.line.me/v1/profile', [
            'headers' => [
                'X-Line-ChannelToken' => $token['access_token'],
            ],
        ]);
        return json_decode($response->getBody(), true);
    }

    protected function mapUserToObject(array $user)
    {
        return (new User())->setRaw($user)->map([
            'id' => $user['mid'],
            'name' => $user['displayName'],
        ]);
    }

    protected function parseAccessToken($body)
    {
        return json_decode($body, true);
    }
}

```

### アクセストークンの取得方法

「The following information is specified in the request body in form-encoded format.」とあったので form_params に必要なパラメータを全て設定し、application/x-www-form-urlencoded を指定して送ってやる。


###ユーザー情報の取得方法

 ヘッダーに X-Line-ChannelToken を設定。


これだけ実装して

- config/service.php に cliend_id などの設定
- config/app.php にプロバイダーの登録 


すればすぐに使える。

使うときはこんな感じで。

```php:app/Http/Controllers/SocialController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Laravel\Socialite\Contracts\Factory as Socialite;

class SocialController extends Controller
{
    protected $socialite;

    public function __construct(Socialite $socialite)
    {
        $this->socialite = $socialite;
    }

    function redirect($provider){
        return $this->socialite->driver('line')->redirect();
    }

    function callback($provider){
        $user = $this->socialite->driver('line')->user();
    }
}



```

このように Socialite は独自ドライバのカスタムも容易で使いやすいので結構良いと思います。