LaravelでLineNotifyの認証からやってみる

[これ](http://qiita.com/ichikawa_0829/items/fd85cd5f73b3d297a5b1)の続きです。

まずは管理画面からサービス登録します
<img width="400" alt="スクリーンショット 2016-09-29 15.39.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/14172/fdfa93fc-e5be-e336-81df-600650e14fff.png">

項目を埋めて登録が完了するとサービス一覧に追加され、その先のページに登録した内容と認証に必要な情報が記載されています。
以下の項目をメモします。
・Client ID
・Client Secret
・Callback URL

では、引き続きLaravelでやってみます。
※とりあえずどういう感じなのか見たくて適当に書いたのでかなり適当です。ごめんなさい。ちゃんとやる時はいい感じのOAuthライブラリ使ってちゃんと書いてください。
※コールバック時にCSRF Tokenミスマッチでエラーになったりしましたが、一旦動かしたかったんでMiddleWare外しました。

```:.env
LINE_NOTIFY_CLIENT_ID=<Client ID>
LINE_NOTIFY_CLIENT_SECRET=<Client Secret>
LINE_NOTIFY_CLIENT_CALLBACK_URI=<Callback URL>
```

```php:config/services.php
<?php
return [

    'line_notify' => [
        'client_id' => env('LINE_NOTIFY_CLIENT_ID'),
        'secret'    => env('LINE_NOTIFY_CLIENT_SECRET'),
        'redirect_uri' => env('LINE_NOTIFY_CLIENT_CALLBACK_URI')
    ]
];
```

```php:app/Http/routes.php
Route::group(['prefix' => 'notify'], function () {
    Route::get('/', 'LineNotifyController@index');
    Route::get('/auth', 'LineNotifyController@redirectToProvider');
    Route::post('/callback', 'LineNotifyController@handleProviderCallback');
    Route::post('/send', 'LineNotifyController@send');
});
```

```php:app/Http/Controllers
<?php

namespace App\Http\Controllers;

use GuzzleHttp\Client;

class LineNotifyController extends Controller
{
    public function index()
    {
        return view('line_notify.index');
    }

    public function redirectToProvider()
    {
        $uri = 'https://notify-bot.line.me/oauth/authorize?' .
            'response_type=code' . '&' .
            'client_id=' . config('services.line_notify.client_id') . '&' .
            'redirect_uri=' . config('services.line_notify.redirect_uri') . '&' .
            'scope=notify' . '&' .
            'state=' . csrf_token() . '&' .
            'response_mode=form_post';
        return redirect($uri);
    }

    public function handleProviderCallback()
    {
        $uri = 'https://notify-bot.line.me/oauth/token';
        $client = new Client();
        $response = $client->post($uri, [
            'headers'     => [
                'Content-Type' => 'application/x-www-form-urlencoded',
            ],
            'form_params' => [
                'grant_type'    => 'authorization_code',
                'code'          => request('code'),
                'redirect_uri'  => config('services.line_notify.redirect_uri'),
                'client_id'     => config('services.line_notify.client_id'),
                'client_secret' => config('services.line_notify.secret')
            ]
        ]);
        // この環境DBとか入れてないんでとりあえずセッションに入れときます
        $access_token = json_decode($response->getBody())->access_token;
        \Session::set('access_token', $access_token);
        return redirect('/notify');
    }

    public function send()
    {
        $uri = 'https://notify-api.line.me/api/notify';
        $client = new Client();
        $client->post($uri, [
            'headers' => [
                'Content-Type'  => 'application/x-www-form-urlencoded',
                'Authorization' => 'Bearer ' . session('access_token'),
            ],
            'form_params' => [
                'message' => request('message', 'Hello World!!')
            ]
        ]);
        return redirect('/notify');
    }
}

```

```php:resources/views/line_notify/index.blade.php
<a href="/notify/auth">Line Notify Auth</a>

@if(Session::has('access_token'))
    <form action="/notify/send" method="post">
        <input type="hidden" value="{{ session('access_token') }}">
        <label>
            メッセージ
            <input type="text" name="message" value="">
        </label>
        <input type="submit" value="送信">
    </form>
@endif
```

これで準備完了です。

アクセスするとこんな画面になります。
<img width="400" alt="スクリーンショット 2016-09-29 17.39.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/14172/64a47dfd-c0a4-fdae-bb84-297530c8bffb.png">

リンクをクリックすると認証画面に飛ばされます
<img width="400" alt="スクリーンショット 2016-09-29 17.40.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/14172/818175a2-739c-2a6c-28a9-b22a7de5a1a8.png">

自分のアカウントで認証をするとトークルームの選択画面に遷移します
<img width="400" alt="スクリーンショット 2016-09-29 17.40.34.png" src="https://qiita-image-store.s3.amazonaws.com/0/14172/ccceedb2-e9e0-5089-4efa-006e05521819.png">


トークルームを選択して「同意して連携する」をクリックすると、自分で設定したコールバックURLにリダイレクトされます。
<img width="400" alt="スクリーンショット 2016-09-29 17.41.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/14172/e13b9466-1ad8-5e4b-7340-3250907bb5be.png">

メッセージ欄に入力して送信をクリックすると
<img width="400" alt="スクリーンショット 2016-09-29 17.41.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/14172/54ea6b6c-8372-5bad-af01-5e5cab732ca9.png">

こんな感じで届きます。
<img width="400" alt="スクリーンショット 2016-09-29 17.47.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/14172/1356978a-5107-3bf8-9fa4-8271266add33.png">


# まとめ
* LineBotを試した時に証明書とか設定したサーバーを作ってあったせいか凄く簡単でした。(その辺ないと嵌まるかも？Herokuとか使えば大丈夫だろうけど)
* 多分ちゃんとしたOAuthライブラリ使えばかなり簡単に実装出来る気がします。
* API Rate Limitは1000call/hourぽいです。

~~*https://line.bots.jp/notify で公開してるので試していただいで大丈夫ですが、告知なしで変更したり閉じたりします。~~
すいません。イタズラが多かったので停止しました。