LINEログインを使って自社サービスとのID連携を実現する方法

この記事は[エイチームブライズアドベントカレンダー](https://qiita.com/advent-calendar/2017/a-t-brides)23日目の記事です。

# はじめに
前回は[LINE Messaging API でできることまとめ【送信編】](https://qiita.com/kakakaori830/items/52e52d969800de61ce28)を書いたので、今回はLINEログインについて書いていきたいと思います。
そしてこのLINEログインって[LINE STORE](https://store.line.me/)のようにLINEのアカウントを使ってログインできるだけだと思っていたら実は[クロネコヤマトのID連携](http://www.kuronekoyamato.co.jp/ytc/campaign/renkei/LINE/)のように自社アカウントとのID連携もできる超素晴らしい機能だったのです。

#手順１：新規channelの作成
Developer Trialアカウントを[LINE@の公式ページ](http://at.line.me/jp/)から作成したら、[LINE Developers](https://developers.line.me/)にログインして新規channelの作成をします。
![スクリーンショット 2017-12-23 11.20.06.png](https://qiita-image-store.s3.amazonaws.com/0/200812/aa499c18-696c-71ad-995f-dd6a628c1402.png)
設定内容はなんとこれだけ。今回はWEBサイトにLINEログインを組み込んでいこうと思います。

#手順2：リダイレクト先URLの設定
画面左側の「アプリの設定」からリダイレクト先URLを設定します。ここにはLINEログインの処理が終わった後のリダイレクト先URLを登録します。リダイレクト先が複数ある場合（例えばLINEログインした後に自社の会員にはAページを、非会員にはBページを表示するとか）は行区切りで複数登録することが可能です。ここのURL登録を忘れるとログイン処理で「Invalid redirect_uri value. Check if it is registered in a LINE developers site.」のエラーが発生するので忘れずに登録しましょう。
![スクリーンショット 2017-12-23 12.13.32.png](https://qiita-image-store.s3.amazonaws.com/0/200812/3b49267a-f12a-576b-a7cf-6a8b3fbd1fd9.png)
これでLINE developers側の登録は完了です。

#手順3：アプリケーション側の準備
ラインログインはこのURL（ https://access.line.me/oauth2/v2.1/authorize ）にクエリパラメータをつけて実装します。今回は必須のパラメータのみを含めて実装します。

```php:
<a href="https://access.line.me/oauth2/v2.1/authorize
            ?response_type=code
            &client_id= チャンネルID
            &redirect_uri=https%3A%2F%2Fexample.com
            &state=乱数
            &scope=profile">LINEログインする</a>
```
各種パラメータの詳細は[こちら](https://developers.line.me/ja/docs/line-login/web/integrate-line-login/)で確認できます。
チャンネルIDはchannel基本設定のページから取得します。
![スクリーンショット 2017-12-23 12.27.39.png](https://qiita-image-store.s3.amazonaws.com/0/200812/5bef6022-2011-6bf2-d076-e88a7aa2dd3a.png)
redirect_uriは手順２で登録したのと同じURLを指定します。
stateはクロスサイトリクエストフォージェリ防止用に設定する乱数です。アプリケーション側で英数字の文字列でランダムに生成する必要があります。
scopeはprofileとopenidが指定できます。今回はID連携を実装するために、ユーザーのプロフィール情報（LINEのUSER ID）が欲しいのでprofileを指定します。

この状態で上記で作った「LINEログインする」をクリックするとLINE側で自動的にセッションが確認され、LINEにログインしていないユーザの場合はこのような画面が表示されます。LINEにログインしているユーザの場合は、LINEログインページの代わりに確認画面が表示されます。
![スクリーンショット 2017-12-23 12.33.27.png](https://qiita-image-store.s3.amazonaws.com/0/200812/67c54fc9-0421-366d-12b5-32c8a54dcf97.png)
そしてその後同意画面が表示され、先ほど設定したscopeに関するアクセスへの同意が求められます。
![スクリーンショット 2017-12-23 12.33.51.png](https://qiita-image-store.s3.amazonaws.com/0/200812/084c2379-26fe-691f-0e35-5b4395bd8571.png)
ここでユーザが「同意する」を押すと、手順2で設定したURLへリダイレクトされます。この時codeとstateというパラメータがついた状態でリダイレクトされてきます。codeはこの後アクセストークンの取得に使用されるコードです。stateは元のリクエストに含まれる値と一致することを、アプリケーション側で検証するためのものになります。

#手順4：アクセストークンを取得する
先ほど取得したcodeを用いてアクセストークンを取得します。

```php:
$postData = array(
  'grant_type'    => 'authorization_code',
  'code'          => $_GET['code'],
  'redirect_uri'  => '手順２で登録したURL',
  'client_id'     => 'チャンネルID（管理画面から取得）',
  'client_secret' => 'チャンネルシークレット（管理画面から取得）'
);

$ch = curl_init();

curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded'));
curl_setopt($ch, CURLOPT_URL, 'https://api.line.me/oauth2/v2.1/token');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);
curl_close($ch);

$json = json_decode($response);
$accessToken = $json->access_token;
```
#手順4：アクセストークンを元にユーザ情報を取得
手順３で取得したアクセストークンを用いてユーザ情報を取得します。

```php:
$ch = curl_init();

curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Bearer ' . $accessToken));
curl_setopt($ch, CURLOPT_URL, 'https://api.line.me/v2/profile');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);
curl_close($ch);

$json = json_decode($response);
```
これでユーザ名、ユーザID、登録しているプロフィール画像が取得できます。あとはアプリケーション側で自分のサービスのIDとの紐付けを行ってやるとID連携が実現するのです。

# おまけ
今回は「LINEログインする」というリンクを押すことで上記のようなユーザ情報取得を行いましたが、手順3のURL（ https://access.line.me/oauth2/v2.1/authorize〜 ）をLINEのアカウント情報のリッチメニューに登録しておくと、LINEブラウザからそのページを開くことになるので、LINEユーザ情報のログインページはスキップされ、[クロネコヤマトのID連携](http://www.kuronekoyamato.co.jp/ytc/campaign/renkei/LINE/)のような挙動を実現することができるのです。（厳密にはちょっと違うけど）

# 最後に
アドベントカレンダー期間中に3回に分けてLINE@のことを書きましたが、試していて感じたのはどれも本当に驚くほど簡単に実装ができる点です。これからLINE@を使ってまだまだたくさんのことができそうなので、アドベントカレンダー後も情報を発信していこうと思います。

# お知らせ
エイチームブライズでは一緒に活躍してくれる優秀な人材を募集中です。
興味のある方はぜひとも[エイチームグループ採用ページ](http://www.a-tm.co.jp/recruit/)（[Webエンジニア詳細ページ](http://www.a-tm.co.jp/recruit/requirements/career/lifestylesupport-webengineer/)）よりお問い合わせ下さい。

# 明日
[エイチームブライズアドベントカレンダー](https://qiita.com/advent-calendar/2017/a-t-brides)23日目の記事は、いかがでしたでしょうか。アドベントカレンダーも残すところあと2日となりました。明日は @mnm0373 が＼エンジニアのココロを刺激♡／モテるデザイナーの秘訣って？について書いてくれるそうです！モテたいデザイナーの皆さんはぜひご覧ください。