Last active
January 14, 2025 15:30
-
-
Save leog/8f713ba75e83d1ddd220455e3a89ee0c to your computer and use it in GitHub Desktop.
Next-Auth Server-side Sign in
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { AuthHandler } from "node_modules/next-auth/core"; | |
| import { getServerAuthSession } from "@/server/auth"; | |
| import { cookies, headers } from "next/headers"; | |
| import { getCsrfToken } from "next-auth/react"; | |
| import { authOptions } from "@/server/auth"; | |
| import { type AuthAction } from "next-auth"; | |
| import { redirect } from "next/navigation"; | |
| import { createHash } from "crypto"; | |
| export default async function Page({ | |
| searchParams, | |
| }: { | |
| searchParams?: Record<string, string | string[] | undefined>; | |
| }) { | |
| // check existing session to avoid redirecting to signin unnecessarily | |
| const session = await getServerAuthSession(); | |
| if (session && req.url) { | |
| redirect(req.url); | |
| } | |
| // getting cookies' name in case we are in a secure environment | |
| const csrfTokenCookieName = | |
| authOptions.cookies?.csrfToken?.name ?? "next-auth.csrf-token"; | |
| const callbackUrlCookieName = | |
| authOptions.cookies?.callbackUrl?.name ?? "next-auth.callback-url"; | |
| // csrf token needed to authenticate, extracted or generated on demand if needed | |
| let csrfToken = cookies().get(csrfTokenCookieName)?.value; | |
| if (!csrfToken) { | |
| const res = await AuthHandler({ | |
| req: { | |
| method: "GET", | |
| action: "csrf" as AuthAction, | |
| providerId: "provider-id", // replace with yours | |
| error: "provider-id", // replace with yours | |
| }, | |
| options: { | |
| ...authOptions, | |
| }, | |
| }); | |
| csrfToken = (res.body as { csrfToken: string }).csrfToken; | |
| } | |
| // consolidating cookies and their values to pass along to generate auth URL | |
| const allCookies = cookies().getAll(); | |
| const csrfTokenHash = createHash("sha256") | |
| .update(`${csrfToken}${process.env.NEXTAUTH_SECRET}`) | |
| .digest("hex"); | |
| const cookiesObject = { | |
| ...{ | |
| [csrfTokenCookieName]: `${csrfToken}|${csrfTokenHash}`, | |
| [callbackUrlCookieName]: callbackFullUrl.href, | |
| }, | |
| ...Object.fromEntries(allCookies.map((c) => [c.name, c.value])), | |
| }; | |
| const data = { | |
| req: { | |
| body: { | |
| csrfToken: csrfToken?.split("|")[0], | |
| callbackUrl, | |
| json: "true", | |
| }, | |
| method: "POST", | |
| cookies: cookiesObject, | |
| headers: Object.fromEntries(headers()), | |
| action: "signin" as AuthAction, | |
| providerId: "provider-id", // replace with yours | |
| error: "provider-id", // replace with yours | |
| }, | |
| options: authOptions, | |
| }; | |
| const res = await AuthHandler(data); | |
| redirect(res.redirect ?? "/"); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The following piece of code works for me, however with some drawbacks:
The drawbacks are: