🍏

ログイン前にアクセスしたURLにリダイレクト

2024/07/18に公開
  • next-auth@5.0.0-beta.19
  • nextjs@14.1

未ログイン状態で認証で保護されたページにアクセスしたとき、ログイン後に元々アクセスしていたページにリダイレクトしたい

実装

middleware → loginページ → login サーバーアクションの順にpathをURLパラメータ経由で渡していく

middleware

redirectToパラメーターをつけてログインページにリダイレクト

import { auth } from "@acme/auth";

export default auth(async (req) => {
  const url = req.nextUrl.clone();
  const isLoggedIn = !!req.auth;
  if (!isLoggedIn) {
    const signInUrl = new URL("/login", url.origin);
    signInUrl.searchParams.set("redirectTo", url.pathname);
    return Response.redirect(signInUrl);
  }
});

// Optionally, don't invoke Middleware on some paths
export const config = {
  matcher: [
    "/((?!api|_next/static|_next/image|favicon.ico|auth|login|$|.*\\.png$).*)",
  ],
};

loginページ(button)

"use client";

import { useSearchParams } from "next/navigation";

import { Button } from "@acme/ui/button";

import { login } from "~/feature/login/action";

type Props = React.HTMLAttributes<HTMLButtonElement>;
const LoginButton = ({ className }: Props) => {
  const params = useSearchParams();
  const redirectTo = params.get("redirectTo");
  console.log("redirectTo", redirectTo);
  const handleLogin = async () => {
    await login({ redirectTo: redirectTo });
  };
  return (
    <Button className={className} onClick={handleLogin}>
      ログイン
    </Button>
  );
};

export default LoginButton;

login server action

"use server";

import { signIn } from "@acme/auth";

interface LoginOptions {
  redirectTo: string | null;
}
export const login = async ({ redirectTo }: LoginOptions) => {
  await signIn("ks-cloud", { redirectTo: redirectTo ?? "/" });
};

Discussion