LINE連動アプリに認可した権限を取り消すのを試してみた

2024.06.14

西田@リテールアプリ共創部マッハチームです

今回はLINEの連動アプリの認可の取り消しを試してみます

概要

LINEログインを組み込んだ連動アプリ(認可済みのアプリ)を 連動アプリに認可した権限を取り消す LINEログインAPIを使って認可を取り消したいと思います

連動アプリの取り消し自体はLINEアプリからユーザー自身の操作で行うことも可能です

なぜ、連動アプリ側で取り消す必要があるのか?

LINEログインの開発ガイドラインの必須事項に以下の項目が記載されています

LINEログインを組み込んだ連動アプリ(ウェブサイトやスマートフォンアプリなど)からユーザーが退会する場合、あるいはユーザーが連動アプリとLINEアプリの連携を解除した場合は、以下を必ず行ってください。

  1. ユーザーがその連動アプリに対して認可していた権限を、連動アプリに認可した権限を取り消すエンドポイントを用いて、ユーザーの代わりに取り消してください。
  2. 退会や連携解除を行ったことで何が起きるのかを、その機能のそば、もしくは会員登録時や連携時にユーザーが同意する規約などに記載してください。

LINEミニアプリ、LIFFアプリ、LINEログインを使ったアプリで、退会やLINEとの連携解除機能がある場合は、退会もしくは連携解除時に認可取り消しAPIを使用し、認可を取り消す必要があります

試してみる

大まかな流れとしては以下になります

  1. LINEログインチャネルのチャネルアクセストークンを発行する
  2. ユーザーのアクセストークンを取得する
  3. チャネルアクセストークンとユーザーのアクセストークンを使って deauthroize エンドポイントを呼び出す

LINEログインチャネルのチャネルアクセストークンを発行する

LINEログインチャネルのチャネルアクセストークンを発行します

LINEのチャネルアクセストークンには4種類あり、LINEログインチャネルで発行できるトークンは、以下の2種類があります

有効期間 発行数
ステートレス 15分 上限なし
v2.1 最大30日間 チャネル毎に30件

今回は、15分しか有効期限がないけれど、上限なしに発行できて、発行する手続きも簡単なステートレスアクセストークンを使います

ステートレスチャネルアクセストークンを発行する こちらの内容をTypeScriptを使って発行していきます

チャネルアクセストークンを発行するには、「チャネルID」と「チャネルシークレット」が必要です。これらはLine Developersのチャネル画面から取得できます

以下はTypeScriptでチャネルアクセストークンを発行する関数です。環境変数に設定した、LINEログインのチャネルIDとチャネルシークレットを使って、 `https://api.line.me/oauth2/v3/token` エンドポイントを呼び出します

export async function issueLoginChannelAccessToken() {
  const response = await fetch("https://api.line.me/oauth2/v3/token", {
    method: "POST",
    headers: {
      "Content-Type": "application/x-www-form-urlencoded",
    },
    body: new URLSearchParams({
      grant_type: "client_credentials",
      client_id: process.env.LINE_LOGIN_CHANNEL_ID!,
      client_secret: process.env.LINE_LOGIN_CHANNEL_SECRET!,
    }),
  });

  if (!response.ok) {
    const text = await response.text();
    throw new Error(
      `Failed to issue access token: ${response.statusText} ${text}`
    );
  }

  const body = (await response.json()) as {
    access_token: string;
    expires_in: number;
  };
  return body;
}

認可取り消しAPIを呼び出す

先ほどの関数で発行するLINEログインチャネルアクセストークンとユーザーのアクセストークンをパラメーターに設定し、 `https://api.line.me/user/v1/deauthorize` エンドポイントを呼び出します

※チャネルアクセストークンの時と違い Content-Type が application/json になることに注意が必要です

連動アプリに認可した権限を取り消す

export async function deauthorize(userAccessToken: string) {
  const channelAccessToken = (await issueLoginChannelAccessToken())
    .access_token;

  const response = await fetch("https://api.line.me/user/v1/deauthorize", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${channelAccessToken}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      userAccessToken,
    }),
  });

  if (!response.ok) {
    const text = await response.text();
    throw new Error(`Failed to deauthorize: ${response.statusText} ${text}`);
  }
  return;
}

呼び出し部分を作成する

フロントからのこれらの関数を呼び出すハンドラー部分を作成します。以下は express を使った例です。 ユーザーからアクセストークンを受け取って、先ほどの関数に渡しています

app.post("/deauthorize", async (req, res) => {
  const userAccessToken = req.body.userAccessToken as string;
  await deauthorize(userAccessToken);
  res.send("OK");
});

フロントからAPIを呼び出す

以下はReactでLIFFを使った例です。liffを使ってユーザーのアクセストークンを取得して、それをAPIに渡しています

import liff from "@line/liff";
import "./App.css";
import { config } from "./config";

function App() {
  const onClick = async () => {
    fetch("https://example.com/deauthorize", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        userAccessToken: await liff.getAccessToken()!,
      }),
    });
  };

  return (
    <>
      <button onClick={onClick}>
        退会
      </button>
    </>
  );
}

export default App;

解除されたことを確認する

LINEアプリから解除されたことを確認できます

設定(歯車マーク) > アカウント > 連動アプリ

連動アプリ一覧を開いて、そこに解除したアプリが表示されてなければ成功です

さいごに

今回は、LINEの連動アプリの認可の取り消しを試してみました。この記事が誰かの役に立てれば幸いです