LINE Login v2がものすごく便利なのに解説した記事が見当たらないので、LINE Messaging APIとの連携を例として書いておきます。(すいません、Salesforce版はありました > http://qiita.com/hhayai/items/c7d1d8e30751871aafc7)
これが使えるとLINE Botで出来ることが格段に増えるのでBot Awardとか狙っている人にはものすごく便利かと。
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からのリクエストを受け取るスクリプト)
<?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ページ)
<!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(ログイン後に飛ばされるページ)
<!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に飛ばすのが当たり前になりそうです。