初めに
LINE通知のアプリを作成するために、LINEのMessaging APIを使用することになり、
LINEログイン(LINEブロバイダー)を対応しているClerkを採用しました。
いろいろと設定することが多かったので、今後忘れないためにまとめました。
1. Next.jsでプロジェクト作成
src/
directory? ... Yes にしました。
npx create-next-app@latest
√ What is your project named? ... my-app(プロジェクト名)
√ Would you like to use TypeScript? ... Yes
√ Would you like to use ESLint? ... Yes
√ Would you like to use Tailwind CSS? ... No / Yes(任意)
√ Would you like your code inside a `src/` directory? ... Yes
√ Would you like to use App Router? (recommended) ... Yes
√ Would you like to use Turbopack for `next dev`? ... No
√ Would you like to customize the import alias (`@/*` by default)? ... No
npm run dev
ログインページ、ログイン後(/dashboard)のページの作成していきます。
今回は、ログインしているユーザーのみ「/dashboard/*」をアクセスできるようにします。
ディレクトリ構成↓↓
MY-APP/
├── node_modules/components
├── public/
├── src
│ └── middleware.ts // Clerkを利用したリダイレクト処理等記述
│ └── app/
│ ├── (auth)/sign-in/[[...sign-in]]/
│ │ └── page.tsx // ログインページ(ソーシャルログインのため初回のみ新規登録)
│ ├── (dashboard)/dashboard/ //ログイン済み(認証済み)なら確認可能
│ │ └── page.tsx
│ ├── components
│ │ └── auth/auth-button.tsx // ログインボタン、ユーザーアイコン(モーダル用)
│ │ └── header/header.module.css
│ │ └── header/header.tsx
│ ├── globals.css
│ ├── layout.tsx
│ ├── page.module.css
│ └── page.tsx // ログイン有無関係なく確認できる
├── .env.local // ClerkやLINEと連携するための環境変数
├── .gitignore
├── eslint.config.mjs
├── next-env.d.ts
├── next.config.ts
├── package-lock.json
├── package.json
├── README.md
└── tsconfig.json
2. Clerk 認証で使用する applications 作成
Clerkでアカウント登録後、Create application でアプリケーションを作成します。
ブロバイダーはLINEのみ選択(Email、Googleの認証も可能ですが、今回はなしにします)
必要なライブラリをインストールしていきます。
npm install @clerk/nextjs
npm install @clerk/localizations
各ファイルに必要な設定記述
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=XXXX
CLERK_SECRET_KEY=XXXX
# https://clerk.com/docs/guides/custom-redirects
# ログインページ指定(ログインしていない場合のリダイレクト先。最初のログインは新規登録になる)
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
# ログイン後にリダイレクトするパス(既存コンポーネントのみ有効)
NEXT_PUBLIC_CLERK_SIGN_IN_FORCE_REDIRECT_URL=/dashboard
NEXT_PUBLIC_CLERK_SIGN_UP_FORCE_REDIRECT_URL=/dashboard
# FORCE_REDIRECTで解決しない場合のリダイレクト先(既存コンポーネントのみ有効)
NEXT_PUBLIC_CLERK_SIGN_IN_FALLBACK_REDIRECT_URL=/dashboard
NEXT_PUBLIC_CLERK_SIGN_UP_FALLBACK_REDIRECT_URL=/dashboard
# サインアウト後は <ClerkProvider afterSignOutUrl={"/"}> で記述します
NEXT_PUBLIC_LINE_ADD_URL=LINEの友達追加URL
import { clerkMiddleware, createRouteMatcher } from "@clerk/nextjs/server";
import { NextResponse } from "next/server";
// ログイン済みユーザーのみにアクセスさせたいルートを定義(プロジェクトに合わせて変更)
const isProtectedRoute = createRouteMatcher([
"/dashboard(.*)", // /dashboard とその下の全ページ
]);
// 全ユーザーにアクセス可能な公開ルートを定義(プロジェクトに合わせて変更)
const isPublicRoute = createRouteMatcher(["/sign-in(.*)"]);
export default clerkMiddleware(async (auth, req) => {
const { userId } = await auth();
// ユーザーがログイン済み かつ 公開ページ(ログインページ)にアクセスしようとした場合
if (userId && isPublicRoute(req)) {
// /dashboardにリダイレクトさせる
const dashboardUrl = new URL("/dashboard", req.url);
return NextResponse.redirect(dashboardUrl);
}
// 認証が必要なページの場合、認証処理をする
// 認証されていない場合「sign-in」にリダイレクト
if (isProtectedRoute(req)) {
await auth.protect();
}
// 上記のどのルールにも当てはまらない場合は、リクエストをそのまま通す(明示記載)
return NextResponse.next();
});
// マニュアル(clerkの案内)従って貼り付け
export const config = {
matcher: [
// Skip Next.js internals and all static files, unless found in search params
"/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)",
// Always run for API routes
"/(api|trpc)(.*)",
],
};
import type { Metadata } from "next";
import { Noto_Sans_JP } from "next/font/google";
import "./globals.css";
// 追加
import { ClerkProvider } from "@clerk/nextjs";
import { jaJP } from "@clerk/localizations";
// フォントオプション設定
const notoSansJP = Noto_Sans_JP({
subsets: ["latin"],
weight: ["400", "500", "700"],
preload: true,
});
export const metadata: Metadata = {
title: "サイト名",
description: "サイト説明",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
// afterSignOutUrlはサインアウト後のリダイレクト先。.envでは指定できないみたい
return (
<ClerkProvider localization={jaJP} afterSignOutUrl={"/"}>
<html lang="ja">
<body className={`${notoSansJP.className} antialiased`}>
{children}
</body>
</html>
</ClerkProvider>
);
}
3. 画面(見た目)のコンポーネントを作成
ログインページを実装します。clerk既存コンポーネントを使用
import { SignIn } from "@clerk/nextjs";
export default function SignInPage() {
return <SignIn />;
}
ログインボタンとユーザーアイコンのコンポーネントを作成します
"use client";
import { SignInButton, useAuth, UserButton } from "@clerk/nextjs";
import Link from "next/link";
const AuthButton = () => {
// セッション情報はこれで取得
const { userId } = useAuth();
// ログイン中の場合は、ユーザーアイコン表示(ログアウトも可能)
if (userId) {
return (
<UserButton
appearance={{
elements: {
avatarBox: "h-10 w-10",
},
}}
/>
);
}
// mode="modal" でモーダル表示にする
// .envに指定している場合「forceRedirectUrl」「fallbackRedirectUrl」をなしでもOK
return (
<>
<button>
<Link
href={process.env.NEXT_PUBLIC_LINE_ADD_URL || "/"}
target="_blank"
rel="noopener"
>
友だち追加する
</Link>
</button>
<SignInButton
mode="modal"
fallbackRedirectUrl={"/dashboard"}
forceRedirectUrl={"/dashboard"}
>
<button>LINEログイン</button>
</SignInButton>
</>
);
};
export default AuthButton;
Headerコンポーネントを作成します。
※CSSの説明は省きます。各自で設定してください
import AuthButton from "../auth/auth-button";
import styles from "./header.module.css";
import Link from "next/link";
const Header = () => {
return (
<header className={styles.header}>
<h1>
<Link href="/">サイト名</Link>
</h1>
<nav>
<AuthButton />
</nav>
</header>
);
};
export default Header;
TOP(Home)を実装します。
import styles from "./page.module.css";
import Header from "./components/header/header";
export default function Home() {
return (
<>
<Header />
<main className={styles.main}>TOPページ(Home)です。</main>
<footer>省略</footer>
</>
);
}
Dashboardを実装します。
import Header from "@/app/components/header/header";
export default function Dashboard() {
return (
<>
<Header />
<main>ダッシュボード。</main>
</>
);
}
npm run dev
LINEログインをクリックすると、モーダルで表示します。
確認:http://localhost:3000/sign-in
確認:http://localhost:3000/dashboard (ログインしていない場合、sign-inにリダイレクト)
モーダルでログインする場合、ユーザーが「/sign-in」を直接アクセスすることはないですが、不正アクセスやログイン失敗など時にリダイレクト先が必要になるため、ログインページも作成しました。
ログインを確認します。LINEで続けるをクリック後、LINEのメールアドレスとパスワードを入力してログインします。
メールアドレスの許可はOFFでも大丈夫です。スクロールして許可するをクリック。
ログイン完了後、指定リダイレクトページ(今回は/dashboard)移動し、ログインボタンではなくユーザーアイコンが表示されていれば無事ログイン完了です。
また、ログイン中に、http://localhost:3000/sign-in に直接アクセスして、指定リダイレクトページ(今回は/dashboard)に移動することも確認します。
ログインするまでは、切換え前後のちらつきが発生すると思うので、ローディング中などで対応すると良いと思います(以下は例になります)
"use client";
import { useAuth, SignIn } from "@clerk/nextjs";
export default function SignInPage() {
// useClerkフックを呼び出し、isLoadedプロパティを取得
const { isLoaded } = useAuth();
if (!isLoaded) {
return <div>ローディング中</div>;
}
return <SignIn />;
}
念のため、https://dashboard.clerk.com/ でも無事ユーザーが登録されたか確認します。作成したアプリケーション選択し、Usersから確認できます。
4. 公式LINEアカウント作成
ログイン機能は完成しましたが、LINEログインしたユーザーにLINE通知するためには、公式LINEアカウントを用意し、その情報をNext.jsとclerkに連携する必要があります。
公式LINEアカウント(LINEビジネスID)作成していきます。
https://www.lycbiz.com/jp/service/line-official-account/ にアクセス
アカウント開設 → LINE公式アカウントをはじめる →
今回はLINEアカウント(普段使っている普通のアカウント)で登録していきます。
本人確認も恐らく必要なるので普段使っているLINEを開いて認証番号を入力します。SMS認証は携帯番号を入力します。
本人確認後、LINE公式アカウントに必要な情報を入力して、確認ボタンを押します。
料金プラン:https://www.lycbiz.com/jp/service/line-official-account/plan/
(無料プランあります)
-
アカウント名:LINEの友だちリストやトーク画面に表示される名称
-
メールアドレス:有効なメールアドレス
-
会社・事業者の所在国・地域:日本
-
業種:適切な業種選択
-
省略・・・
申し込み完了後は、以下ように、「アカウント認証をリクエストする」と表示されますが、あとでも対応可能なので「あとで認証を行う」を押して先へ進みます。
同意完了後、作成完了です。
5. 公式LINEアカウントに必要な設定をする。
1. ホーム(https://manager.line.biz/) → アカウント選択 → プロフィール設定(任意)
2. ホーム → アカウント選択 → チャット:オフ(任意)
3. ホーム → アカウント選択 → トークルーム管理 → あいさつメッセージ の設定
4. ホーム → アカウント選択 → 設定 → アカウント認証をリクエスト(任意だが本番の場合推奨)
5. ホーム → アカウント選択 → 設定 → Messaging APIを利用する(ブロバイダーと「Messaging API」チャネルを作成)
Messaging APIを利用する をクリックします
LINE Developers(https://developers.line.biz/console/) で使用する名前(開発者)とメールアドレスを入力します。
LINE Developers(https://developers.line.biz/console/) で使用するブロバイダーを作成します。「LINEログイン」チャネル、「Messaging API」チャネルを管理するために使用するブロバイダー名を入力します。「LINEログイン」チャネルに関しては後ほど作成します。
「Messaging API」チャネルのプライバシーポリシーと利用規約ページは空でもOKですが、本番で使用する場合は、作成して入力したほうがよいとは思います。
OKを押すと、ブロバイダーと「Messaging API」チャネルが作成されます。
Messaging APIのステータスが利用中になればOKです。
6. コンソール設定(https://developers.line.biz/console/) → ブロバイダー選択 → 作成した「Messaging API」チャネル選択 → Messaging API設定
作成したブロバイダー選択します
作成した「Messaging API」チャネルを選択します
Messaging API設定を選択します
下までスクロールして、発行ボタン押して、チャネルアクセストークンを作成します。LINE通知するための必要な値になります。
本番で利用する場合は、セキュリティ設定を選択して、IPアドレスの設定もします。
7. コンソール設定 → 作成したブロバイダー選択 → 新規チャネル作成 → 「LINE ログイン」
新規チャネルを作成していきます。
LINEログイン を選択します。
必要な項目を入力します。
-
チャネルの種類:LINE ログイン
-
プロバイダー:作成したブロバイダー名
-
会社・事業者の所在国・地域:日本
-
チャネルアイコン:clerk認証時(LINEログインまたは新規登録時)に表示したいLINEアイコン
-
チャネル名:clerk認証時(LINEログインまたは新規登録時)に表示したい名前
-
チャネル説明:clerk認証時(LINEログインまたは新規登録時)に表示したい説明を入力
-
アプリタイプ :ウェブアプリ(ネイティブアプリも選択可能)
-
2 要素認証の必須化:ON
-
メールアドレス:有効なメールアドレス
-
プライバシーポリシー URL:https:XXX(任意だが本番の設定推奨)
-
利用規約:https:XXX(任意だが本番の設定推奨)
必須項目など入力したら、作成を押します。
8. コンソール設定 → 作成したブロバイダー選択 → 作成した「LINE ログイン」チャネル選択 → 「チャネル基本設定」
「LINE ログイン」選択します。
下までスクロールすると、リンクされたLINE公式アカウントがあるので「編集」をクリックします。
作成した公式LINEアカウント選択して、「更新」をクリックします。
ちなみにメールアドレス取得権限の申請は任意ですが、申請した場合、clerk認証時(LINEログインまたは新規登録時)のメールアドレス(LINEで設定しているメールアドレス)取得する許可を表示できます↓↓
ただ申請するには、プライバシーポリシーなどのページで「あなたのアプリが、取得したメールアドレスを、どんな目的で、どのように利用するのかを、ユーザーにきちんと説明しているか」の内容を記載したスクショが必要になります。そのためこの記事での設定は省略します。
6. Clerk と 「LINE ログイン」チャネルを連携する
https://dashboard.clerk.com/apps → アプリケーション選択 → Configureをクリックします。します
SSO connections → LINEの設定(歯車のアイコン)をクリックします。
Clerk と 「LINE ログイン」チャネルを連携するための情報を入力して、Upadateを押します。
※「Messaging API」チャネルではなく「LINE ログイン」チャネルのIDとシークレットを入力します。また、Callback URLの値は「LINE ログイン」チャネルの設定で必要なのでコピーします。
「LINE ログイン」チャネルの画面に移動し、LINEログイン設定を選択します。
コールバックURLの編集ボタンを押して、先ほどコピーしたCallback URLを貼り付け、更新ボタンを押します。
最後に、開発中 → 公開 にします
無事連携できたかログインで確認していきます。(ログインしている場合は、ユーザーアイコンからログアウトできます。また登録したユーザーの削除はclerkの画面から削除できます)
ログイン時に赤枠の部分がLINEログインチャネルの設定した値になっていれば、無事連携完了になります。
終わりに
記事が長くなるので、LINE通知(Messaging API)処理は、次回の記事で作成いたします。