LoginSignup
78
65

More than 5 years have passed since last update.

LINE Botが超便利になるLINE Loginバージョン2の解説と実装方法(Heroku+PHP)

Last updated at Posted at 2017-02-07

LINE Login v2がものすごく便利なのに解説した記事が見当たらないので、LINE Messaging APIとの連携を例として書いておきます。(すいません、Salesforce版はありました > http://qiita.com/hhayai/items/c7d1d8e30751871aafc7)
これが使えるとLINE Botで出来ることが格段に増えるのでBot Awardとか狙っている人にはものすごく便利かと。

LINE Bot Awards

LINE Login バージョン2とMessaging APIを組み合わせて出来ること

  • LINEのIn AppブラウザでユーザーはLINEのアカウントを利用してログインできる
  • 2度目以降はIDパスワード入力無しの自動ログイン
  • ログイン後はブラウザ上でもLINEの表示名、サムネイル、Messaging APIと共通のuserIdが取得できる(それを使ってメッセージのPushができる)

準備

  • LINE Business CenterでLINE Messaging APIとLINE Loginのアカウントを開設
  • Messaging APIのChannel SecretとChannel Access Token、LINE LoginのChannel IDとChannel Secretを控えとく

  • LINE Messaging APIの設定を終わらせておきます。わからない方はググって。
  • LINE LoginのTechnical Configurationにログイン後のコールバック先を入力 ← 忘れがち

  • CSRF対策用にaura/sessionを入れときます。
composer require composer require aura/session

index.php(Botからのリクエストを受け取るスクリプト)

index.php
<?php

require_once __DIR__ . '/vendor/autoload.php';

$httpClient = new \LINE\LINEBot\HTTPClient\CurlHTTPClient(getenv('CHANNEL_ACCESS_TOKEN'));
$bot = new \LINE\LINEBot($httpClient, ['channelSecret' => getenv('CHANNEL_SECRET')]);

$signature = $_SERVER['HTTP_' . \LINE\LINEBot\Constant\HTTPHeader::LINE_SIGNATURE];
try {
  $events = $bot->parseEventRequest(file_get_contents('php://input'), $signature);
} catch(\LINE\LINEBot\Exception\InvalidSignatureException $e) {
  error_log('parseEventRequest failed. InvalidSignatureException => '.var_export($e, true));
} catch(\LINE\LINEBot\Exception\UnknownEventTypeException $e) {
  error_log('parseEventRequest failed. UnknownEventTypeException => '.var_export($e, true));
} catch(\LINE\LINEBot\Exception\UnknownMessageTypeException $e) {
  error_log('parseEventRequest failed. UnknownMessageTypeException => '.var_export($e, true));
} catch(\LINE\LINEBot\Exception\InvalidEventRequestException $e) {
  error_log('parseEventRequest failed. InvalidEventRequestException => '.var_export($e, true));
}

foreach ($events as $event) {
  $bot->replyText($event->getReplyToken(), "https://" . $_SERVER["HTTP_HOST"] .  "/line_login.php");
}

?>

イベントに対してログイン用のWebサイトへのリンクを返信するだけ。

line_login.php(ログインボタンを表示するWebページ)

line_login.php
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>
<html xmlns='http://www.w3.org/1999/xhtml' lang='ja' xml:lang='ja'>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>
<title>LINE Login v2 Sample</title>
</head>
<body>
<?php

require_once __DIR__ . '/vendor/autoload.php';

$session_factory = new \Aura\Session\SessionFactory;
$session = $session_factory->newInstance($_COOKIE);
$segment = $session->getSegment('Vendor\Package\ClassName');

$csrf_value = $session->getCsrfToken()->getValue();

$callback = urlencode('https://' . $_SERVER['HTTP_HOST']  . '/line_callback.php');
$url = 'https://access.line.me/dialog/oauth/weblogin?response_type=code&client_id=' . getenv('LOGIN_CHANNEL_ID') . '&redirect_uri=' . $callback . '&state=' . $csrf_value;
echo '<a href=' . $url . '><button class="contact">LINE Login v2 Sample</button></a>';

?>
</body>
</html>

ログインボタンを表示する用のページ。このページ表示せずいきなりログインAPI叩くのも可能。

line_callback.php(ログイン後に飛ばされるページ)

line_login.php
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>
<html xmlns='http://www.w3.org/1999/xhtml' lang='ja' xml:lang='ja'>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>
<title>LINE Login v2 Sample Callback</title>
</head>
<body>
<?php

require_once __DIR__ . '/vendor/autoload.php';

$unsafe = $_SERVER['REQUEST_METHOD'] == 'POST'
       || $_SERVER['REQUEST_METHOD'] == 'PUT'
       || $_SERVER['REQUEST_METHOD'] == 'DELETE';

$session_factory = new \Aura\Session\SessionFactory;
$session = $session_factory->newInstance($_COOKIE);
$csrf_value = $_GET['state'];
$csrf_token = $session->getCsrfToken();
if ($unsafe || !$csrf_token->isValid($csrf_value)) {
  return;
}

$callback = 'https://' . $_SERVER['HTTP_HOST']  . '/line_callback.php';
if (isset($_GET['code'])) {
  $url = 'https://api.line.me/v2/oauth/accessToken';
  $data = array(
    'grant_type' => 'authorization_code',
    'client_id' => getenv('LOGIN_CHANNEL_ID'),
    'client_secret' => getenv('LOGIN_CHANNEL_SECRET'),
    'code' => $_GET['code'],
    'redirect_uri' => $callback
  );
  $data = http_build_query($data, '', '&');
  $header = array(
    'Content-Type: application/x-www-form-urlencoded'
  );
  $context = array(
    'http' => array(
      'method'  => 'POST',
      'header'  => implode('\r\n', $header),
      'content' => $data
    )
  );
  $resultString = file_get_contents($url, false, stream_context_create($context));
  $result = json_decode($resultString, true);

  if(isset($result['access_token'])) {
    $url = 'https://api.line.me/v2/profile';
    $context = array(
      'http' => array(
      'method'  => 'GET',
      'header'  => 'Authorization: Bearer '. $result['access_token']
      )
    );
    $profileString = file_get_contents($url, false, stream_context_create($context));
    $profile = json_decode($profileString, true);
        echo '<img src="' . htmlspecialchars($profile["pictureUrl"], ENT_QUOTES) . '" />';
    echo '<p>displayName : ' . htmlspecialchars($profile["displayName"], ENT_QUOTES) . '</p>';
    echo '<p>userId : ' . htmlspecialchars($profile["userId"], ENT_QUOTES) . '</p>';

    $httpClient = new \LINE\LINEBot\HTTPClient\CurlHTTPClient(getenv('CHANNEL_ACCESS_TOKEN'));
    $bot = new \LINE\LINEBot($httpClient, ['channelSecret' => getenv('CHANNEL_SECRET')]);
    $bot->pushMessage($profile["userId"], new \LINE\LINEBot\MessageBuilder\TextMessageBuilder('Logged in via LINE Login v2.'));
  }
}
else {
  echo '<p>Login Failed.</p>';
}
?>
</body>
</html>

結果

友達追加するとリンクが送られます。

ログインページ。

ボタンをタップするとログインを試みます。

ログインしたことないLogin先の場合は認証画面が開きます。一度同意すると次回からは表示されず、自動でログイン。

ログイン完了。Web上でLINEアカウントの表示名やサムネイル、ステータスメッセージ、ユーザーIDが取得できます。

このユーザーIDはLINE Messaging APIと共通なので、Push APIを利用してユーザーにメッセージ送信できます。

こんな感じ。Botとのトーク画面にメッセージを送信できました。

まとめ

LINE Loginを上手く使うとBotのインターフェースを考える時、トーク画面上でのコミュニケーションに限定されず必要に応じてWebに遷移させればいいので開発者にもユーザーにもとても優しいですね。

設定画面とかはWebに飛ばすのが当たり前になりそうです。

78
65
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
78
65