4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Turso 構成で、認証をつけるなら Clerk

Posted at

以前の記事

またも以前の記事に関連していますが、
Tursoの場合、認証基盤がないのでAuth.js(旧NextAuth)で作ろうと書いていたのですが、
Turso公式がClerkを推していました。

こちらも実装が非常に楽ではあったのですが、
authMiddlewareがdeprecatedになりClaude3.7では知識がインプットされていなかったため、
新しい方のclerkMiddlewareによる実装を記載します。

Clerkの認証設定

srcディレクトリがあれば、その直下にmiddleware.ts
なければ、プロジェクトルートにmiddleware.tsを作成します。

src/middleware.ts
import { clerkMiddleware } from '@clerk/nextjs/server'

export default clerkMiddleware()

// 認証したい
import { clerkMiddleware, createRouteMatcher } from "@clerk/nextjs/server";

// パブリックルートの定義
const isPublicRoute = createRouteMatcher([
  "/",
  "/public"
]);

export default clerkMiddleware(async (auth, request) => {
  if (!isPublicRoute(request)) {
    await auth.protect()
  }
})

export const config = {
  matcher: ["/((?!.+\\.[\\w]+$|_next).*)", "/", "/(api|trpc)(.*)"],
}; 

ログイン画面の例

/sign-in/page.tsx
'use client';

import { SignIn } from '@clerk/nextjs';
import { useRouter } from 'next/navigation';
import { useEffect } from 'react';
import { useClerk } from '@clerk/nextjs';

export default function SignInPage() {
  const router = useRouter();
  const { session } = useClerk();

  // ユーザーが既にログインしている場合はマイページにリダイレクト
  useEffect(() => {
    if (session) {
      router.push('/mypage');
    }
  }, [session, router]);

  return (
    <div className="flex min-h-screen flex-col items-center justify-center p-4">
      <div className="w-full max-w-md">
        <h1 className="mb-8 text-center text-3xl font-bold text-white">ログイン</h1>
        <div className="rounded-lg bg-white/90 p-6 shadow-lg">
          <SignIn
            appearance={{
              elements: {
                formButtonPrimary: 'bg-blue-500 hover:bg-blue-600 text-sm normal-case',
                card: 'bg-transparent shadow-none',
              },
            }}
            routing="path"
            path="/sign-in"
            redirectUrl="/mypage"
          />
        </div>
      </div>
    </div>
  );
} 

アカウント登録画面の例

/sign-up/page.tsx
'use client';

import { SignUp } from '@clerk/nextjs';
import { useRouter } from 'next/navigation';
import { useEffect } from 'react';
import { useClerk } from '@clerk/nextjs';

export default function SignUpPage() {
  const router = useRouter();
  const { session } = useClerk();

  // ユーザーが既にログインしている場合はマップページにリダイレクト
  useEffect(() => {
    if (session) {
      router.push('/mypage');
    }
  }, [session, router]);

  return (
    <div className="flex min-h-screen flex-col items-center justify-center p-4">
      <div className="w-full max-w-md">
        <h1 className="mb-8 text-center text-3xl font-bold text-white">アカウント登録</h1>
        <div className="rounded-lg bg-white/90 p-6 shadow-lg">
          <SignUp
            appearance={{
              elements: {
                formButtonPrimary: 'bg-blue-500 hover:bg-blue-600 text-sm normal-case',
                card: 'bg-transparent shadow-none',
              },
            }}
            routing="path"
            path="/sign-up"
            redirectUrl="/mypage"
          />
        </div>
        <div className="mt-4 text-center">
          <button
            onClick={() => router.push('/sign-in')}
            className="text-white underline hover:text-blue-300"
          >
            既にアカウントをお持ちの方はこちら
          </button>
        </div>
      </div>
    </div>
  );
} 
4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?