Hero img
Lineアプリを作成サーバ編

NextjsでLineアプリを作りました。(サーバ編)

Line liffのログインができ、ユーザーの情報を取れるようになったけどその次に何をすればいいのか?


目次

  • 目標
  • 前回
  • サーバー側
  • 環境
  • サーバーとクライアント
  • クライアント
  • サーバー
  • 公式情報
  • まとめ

目標

Lineのユーザー情報をサーバー側で保持する。

ソースコード

以下のプログラムの使用およびその効果に関して、いかなる責任も負いません。本番で使用される際は十分気を付けてご利用ください。

前回

前回はクライアント側でログインし、プロファイルを取得することができました。

サーバー側

サーバーでユーザーの情報をどのように取得すればいいのか。
それはクライアント側からアクセストークンをもらい、Lineのサーバーに問い合わせ検証後、ユーザーの情報を取得します。

具体的流れ

  1. 1.クライアント側でアクセストークンを取得する。
  2. 2.サーバーにアクセストークンを投げる
  3. 3.受け取ったアクセストークンは有効なのかをLineに問い合わせる。
  4. 4.アクセストークンを使ってユーザーの情報を取得する。

環境

  • Nextjs14
  • Liff2.21.2
  • SSL環境 開発環境実装方法はこちら

サーバーとクライアント

ユーザーの情報を取得するにはクライアントから直接情報をもらうのではなく、アクセストークンを使用して、ユーザーの情報を取得します。
そのため、ここではサーバーの実装、クライアント側の実装の両方が必要となります。

認証関係については公式の通りやって行きます。

react-line-access-token

クライアント

クライアント側でアクセストークンをサーバーに投げます。
単純にgetAccessToken()を使うだけです。

'use client'
/* eslint-disable */
import React,{useEffect ,useState} from "react";
import liff from '@line/liff';

export default function Home() {
  const [lifobj, setLifobj] = useState({});
  useEffect(() => {
    liff
      .init({
        liffId: process.env.NEXT_PUBLIC_APP_LIFF_ID || ''
      })
      .then(() => {
        console.log("LIFF init succeeded.");
        setLifobj(liff);
      }
      
      )
      .catch((e) => {
        console.log("LIFF init failed.");

      });
  }, []);

  const login = () => { liff.login() }

  if(Object.keys(lifobj).length && !lifobj.isLoggedIn() ){
    console.log("LOGINS???")
   
  return <button onClick={(()=>login())}>login</button>
  }



  const postData = async () => {
    let token = {"actkn" : lifobj.getAccessToken()};
    try {
      const response = await fetch("api/login", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify( token )
      });

      if (!response.ok) {
        throw new Error("Network response was not ok");
      }

      const data = await response.json();
      console.log(data);
    } catch (error) {
      console.log(error);
    }
  };


  return (
    <div>
      <p>LINEDEMO</p>
      <button onClick={(()=>postData())}>post</button>
    </div>
  )
}

クライアントはアクセストークンをサーバー側投げるだけなので複雑なヶ所は特にないかな? 

サーバー

サーバー側では受け取ったアクセストークンをlineに問い合わせ、その後プロフィール情報を取得します。

api/login/route.ts

import { NextResponse, NextRequest } from 'next/server';

// Fetch line user profile
const fetchUserProfile = async (accessToken: string) => {
    const url = 'https://api.line.me/v2/profile';
    const response = await fetch(url, {
        headers: {
            'Authorization': `Bearer ${accessToken}`
        }
    });
    const data = await response.json();
    return data;
}

// Verify Line access token
const verifyAccessToken = async (accessToken: string) => {
    const url = 'https://api.line.me/oauth2/v2.1/verify';
    const params = new URLSearchParams({
        access_token: accessToken,
    });

    try {
        const response = await fetch(`${url}?${params}`);
        const data = await response.json();
        //クライアントID
        if (data.client_id !== 11111111 && data.expires_in > 0) {
            return true;
        }
        return false;
    } catch (error) {
        // Access token is invalid
        return false;
    }
}
// Handle POST request
export const POST = async (req: NextRequest, res: NextResponse) => {
    const  body  = await req.json();
    console.log(body);
    if (await verifyAccessToken(body.actkn)) {
        console.log("correct");
        const userProfile = await fetchUserProfile(body.actkn);
        console.log(userProfile);
        return new Response(JSON.stringify(userProfile), {
            status: 200,
        })
    }
    return new Response(JSON.stringify({ verified: false }), {
        status: 401,
    })
}

サーバーは一度アクセストークンを受け取ってverifyにパラメーター付でGETしています。
その後返って来る値でこれは有効なトークンなのかを判断し、その後ユーザーの情報を取得します。

クライアントID

公式ではクライアントIDを検証してねと書いてあるので「data.client_id」を追加している。  

next-line-client-id

公式情報

アクセストークンの有効性を検証

ユーザープロフィールを取得する

まとめ

line公式がAPI関係を分かりやすく開示してくれているため、比較的簡単に実装できる。ありがたい。
本番となるとやっぱり、セッションID、トークン、クッキーとかを考えないと...orz

関連記事

コメント

コメントを書く

質問や、間違いがありましたら、お気軽にどうぞ

※お名前とコメントの内容を入力してください。
※全てこのブログ上に公表されます。
※許可なく管理者によって修正・削除する場合がございます。 詳しくはプライバシーポリシーを参照ください