AI AGENT FACTORYAIエージェント工場見学 ACTIVE

LINEログインで「Invalid redirect_uri」エラーが出たときの完全解決法

LINEログインを実装中に Invalid redirect_uri が出たら、LINE Developersコンソールに登録したコールバックURLと、実際にリクエストで送っているURLが1文字も違わず一致していないのが原因です。この記事では、エラーの仕組みから設定手順・よくある落とし穴まで、コード例つきで順番に解説します。


仕組みの全体像(図解)

flowchart TD
    A[ユーザーがLINEログインボタンをクリック] --> B[アプリがLINE認証URLを生成]
    B --> C[redirect_uriをURLパラメータに含める]
    C --> D{LINEサーバーが照合}
    D -- 登録済みURLと一致 --> E[認証画面を表示]
    D -- 不一致 --> F[Invalid redirect_uri エラー]
    E --> G[ユーザーが許可]
    G --> H[codeをredirect_uriに返す]
    H --> I[アプリサーバーがcodeを受け取る]
    I --> J[アクセストークンを取得]
    J --> K[ユーザー情報を取得してログイン完了]

前提:このエラーが起きる理由

LINE Loginの認証フロー(OAuth 2.0)では、アプリが認証URLを組み立てるときに redirect_uri パラメータを含めます。LINEサーバーはそのURLを、LINE Developersコンソールの「コールバックURL」欄に登録されているURLと完全一致で比較します。

https://access.line.me/oauth2/v2.1/authorize
  ?response_type=code
  &client_id=YOUR_CHANNEL_ID
  &redirect_uri=https%3A%2F%2Fexample.com%2Fcallback   ← ここが一致しないとエラー
  &state=RANDOM_STRING
  &scope=profile%20openid

「ほぼ同じ」では通りません。末尾スラッシュ1つ、httphttps の違い、ポート番号の有無——すべてが不一致の原因になります。


手順1:LINE Developersコンソールでコールバックを確認する

  1. LINE Developers にログインします。
  2. 左メニューから Providers(プロバイダー) → 対象の Channel(チャネル) を選択します。
  3. タブから LINE Login を選び、「コールバックURL」 欄を開きます。
  4. 登録されているURLを正確にメモします(コピー推奨)。
注意: 「LINE Login」チャネルと「Messaging API」チャネルは別物です。LINEログインの設定は必ず「LINE Login」タイプのチャネルで行ってください。

手順2:コードで使っている redirect_uri を確認する

アプリ内で認証URLを組み立てている箇所を探します。

Python(Flaskの例)

import os
from urllib.parse import urlencode

LINE_CHANNEL_ID = os.environ["LINE_CHANNEL_ID"]
REDIRECT_URI = os.environ["LINE_REDIRECT_URI"]  # 環境変数から取得する

def build_line_auth_url(state: str) -> str:
    params = {
        "response_type": "code",
        "client_id": LINE_CHANNEL_ID,
        "redirect_uri": REDIRECT_URI,
        "state": state,
        "scope": "profile openid",
    }
    return "https://access.line.me/oauth2/v2.1/authorize?" + urlencode(params)

Node.js(Expressの例)

const REDIRECT_URI = process.env.LINE_REDIRECT_URI;

function buildLineAuthUrl(state) {
  const params = new URLSearchParams({
    response_type: "code",
    client_id: process.env.LINE_CHANNEL_ID,
    redirect_uri: REDIRECT_URI,
    state: state,
    scope: "profile openid",
  });
  return `https://access.line.me/oauth2/v2.1/authorize?${params}`;
}

PHP(シンプルな例)

$redirectUri = getenv('LINE_REDIRECT_URI');
$params = http_build_query([
    'response_type' => 'code',
    'client_id'     => getenv('LINE_CHANNEL_ID'),
    'redirect_uri'  => $redirectUri,
    'state'         => bin2hex(random_bytes(16)),
    'scope'         => 'profile openid',
]);
$authUrl = 'https://access.line.me/oauth2/v2.1/authorize?' . $params;

コードで組み立てた redirect_uri の値と、コンソールに登録したURLを並べて目視比較してください。


手順3:コンソールに正しいURLを登録する

  1. コンソールの「コールバックURL」欄の 「編集」 をクリックします。
  2. 実際にアプリが送るURLを そのまま 入力します。
  3. 「更新」 を押して保存します。

複数の環境(ローカル・ステージング・本番)を使う場合は、複数行に分けて登録できます。

# 登録例(1行ずつ入力)
http://localhost:3000/callback
https://staging.example.com/callback
https://example.com/callback
ローカル開発で localhost は使える? はい。LINE Developersは http://localhost 始まりのURLを登録できます。http://localhost:3000/callback のようにポート番号込みで登録しましょう。127.0.0.1localhost は別URLとして扱われるので注意。

手順4:トークン取得時も同じ redirect_uri を使う

認証コード(code)を受け取った後、アクセストークンを取得するAPIにも redirect_uri を送る必要があります。この値も認証URLで使ったものと完全一致させてください。

Python(トークン取得)

import requests

def get_access_token(code: str) -> dict:
    response = requests.post(
        "https://api.line.me/oauth2/v2.1/token",
        data={
            "grant_type": "authorization_code",
            "code": code,
            "redirect_uri": REDIRECT_URI,  # ← 認証URLで使った値と同じ
            "client_id": LINE_CHANNEL_ID,
            "client_secret": os.environ["LINE_CHANNEL_SECRET"],
        },
        headers={"Content-Type": "application/x-www-form-urlencoded"},
    )
    response.raise_for_status()
    return response.json()

Node.js(トークン取得)

async function getAccessToken(code) {
  const params = new URLSearchParams({
    grant_type: "authorization_code",
    code: code,
    redirect_uri: REDIRECT_URI,  // ← 認証URLで使った値と同じ
    client_id: process.env.LINE_CHANNEL_ID,
    client_secret: process.env.LINE_CHANNEL_SECRET,
  });

  const res = await fetch("https://api.line.me/oauth2/v2.1/token", {
    method: "POST",
    headers: { "Content-Type": "application/x-www-form-urlencoded" },
    body: params,
  });
  if (!res.ok) throw new Error(await res.text());
  return res.json();
}

よくあるエラーと対処

エラー1:末尾スラッシュの不一致

症状: コンソールに https://example.com/callback と登録しているのに、コードが https://example.com/callback/ を送っている(または逆)。

対処: コンソールとコードのどちらかに揃えます。どちらが正しいかではなく、一致しているかどうかが全てです。

# NGの例(末尾スラッシュが違う)
コンソール: https://example.com/callback
コード送信: https://example.com/callback/

# OKの例(一致)
コンソール: https://example.com/callback
コード送信: https://example.com/callback

エラー2:HTTP と HTTPS の混在

症状: ローカルは http:// で開発していたのに、本番URLを https:// で登録し忘れた(または逆)。

対処: 環境ごとに使うURLを .env ファイルで管理し、デプロイ時に差し替えます。

# .env.local
LINE_REDIRECT_URI=http://localhost:3000/callback

# .env.production
LINE_REDIRECT_URI=https://example.com/callback

エラー3:ポート番号の有無

症状: ローカルで http://localhost:3000/callback を使っているのに、コンソールに http://localhost/callback(ポートなし)しか登録していない。

対処: ポート番号付きで登録します。

# コンソールに追加登録する
http://localhost:3000/callback

エラー4:URLエンコードの二重適用

症状: redirect_uri を手動で %2F などにエンコードしてから、さらに urlencode に通している。

対処: エンコードは urlencode / URLSearchParams などのライブラリに任せ、生のURLを渡すだけにします。

# NG:自分でエンコードしてからさらにurlencode
redirect_uri = "https%3A%2F%2Fexample.com%2Fcallback"  # 手動エンコード済
params = urlencode({"redirect_uri": redirect_uri})      # 二重エンコードになる

# OK:生のURLをそのまま渡す
redirect_uri = "https://example.com/callback"
params = urlencode({"redirect_uri": redirect_uri})      # ライブラリが適切にエンコード

エラー5:チャネルIDとコールバックURLの組み合わせ違い

症状: 複数のLINEチャネルを持っていて、チャネルAのIDでチャネルBのコールバックURLを使っている。

対処: チャネルID(client_id)と、そのチャネルのコンソールに登録したURLがセットで一致しているかを確認します。

# それぞれのチャネルでIDとコールバックURLを確認する
チャネルA: channel_id=1234567890 → callback=https://app-a.example.com/callback
チャネルB: channel_id=0987654321 → callback=https://app-b.example.com/callback

エラー6:コンソールの保存忘れ

症状: コンソールでURLを入力したが「更新」ボタンを押さずにページを離れた。

対処: 設定変更後は必ず 「更新」 ボタンをクリックし、ページを再読み込みして保存内容を目視確認します。コンソールの変更反映には数秒〜数十秒かかる場合があります。


確認チェックリスト

設定後、以下を上から順に確認してください。

  • [ ] コンソールの「コールバックURL」欄に正しいURLが登録されている
  • [ ] コード内の redirect_uri とコンソールのURLが1文字単位で一致している
  • [ ] スキーム(http / https)が一致している
  • [ ] ポート番号の有無が一致している
  • [ ] 末尾スラッシュの有無が一致している
  • [ ] URLを手動エンコードしていない(ライブラリに任せている)
  • [ ] トークン取得時の redirect_uri も認証時と同じ値を使っている
  • [ ] 複数チャネルがある場合、client_idredirect_uri が同じチャネルのものになっている

まとめ(次の一歩)

Invalid redirect_uri エラーの原因は、ほぼ確実に「コンソール登録値とコード送信値の不一致」です。エラーに直面したら「どこかが1文字違う」という前提で、コンソールとコードを並べて比較するのが最短の解決策です。

次の一歩として試すこと:

  1. .env ファイルで redirect_uri を一元管理し、ハードコードを排除する。
  2. ステージング・本番で環境ごとの .env を分け、デプロイ時の差し替えミスをなくす。
  3. LINE Loginの最新の仕様や制約は LINE Developersの公式ドキュメント で随時確認する。

← 攻略ガイド一覧へ