Skip to content

LIFF 認証 ― userId を信じるか?

📖この章のキーワード
用語意味なぜ重要か
LIFFLINE Front-end Framework。LINE 内でWebアプリを動かす仕組みユーザー情報を取得できる
ID トークンLINE が署名した JWT。ユーザーの身元を証明するサーバー側で検証することで改竄を検出
なりすまし他のユーザーの ID を使って偽のリクエストを送ることuserId を直接信用すると発生
JWTJSON Web Token。署名付きの情報トークンペイロード + 署名で改竄検出が可能

Phase 1: 観察

LIFF(LINE Front-end Framework)アプリでは、ユーザーの LINE ID を取得できます。

javascript
// フロントエンド(LIFF SDK)
const profile = await liff.getProfile();
const userId = profile.userId;

// これをサーバーに送信
fetch('/api/reserve', {
    body: JSON.stringify({ userId: userId, ... })
});

サーバー側で $request->input('userId') をそのまま使うとどうなるでしょうか?

php
// ❌ 危険: クライアントから送られた userId を直接信用
$userId = $request->input('userId');
$friend = Friend::where('friend_id', $userId)->first();

LIBOT の実装:

php
// ✅ 安全: ID トークンを LINE サーバーで検証
// Liff.php(概要)
// Label: exemplar

public function getUserProfile(string $idToken): array
{
    // LINE の検証エンドポイントに問い合わせ
    $response = Http::post('https://api.line.me/oauth2/v2.1/verify', [
        'id_token' => $idToken,
        'client_id' => $this->channelId,
    ]);

    $data = $response->json();

    // 有効期限チェック
    if ($data['exp'] < time()) {
        throw new \Exception('Token expired');
    }

    // 検証済みの userId を返す
    return ['userId' => $data['sub'], 'name' => $data['name']];
}

Phase 2: 判断

AI禁止ゾーン
  • $request->input('userId') を直接使うと、どんな攻撃 が可能になりますか?
  • ID トークン検証は 何を保証 しますか?
  • トークンの 有効期限チェック はなぜ必要ですか?

AIに聞く前に、自分の頭で考えてみましょう。

テキストを入力すると有効になります