From 211594130eac7d0586b6835acd2169b0f0d2a2d4 Mon Sep 17 00:00:00 2001 From: Mackenly Jones <53151058+mackenly@users.noreply.github.com> Date: Sun, 10 Nov 2024 22:06:19 -0500 Subject: [PATCH 1/9] Adds fullstack nextjs auth tutorial draft --- .../docs/developer-spotlight/index.mdx | 7 + ...ication-with-next-js-and-cloudflare-d1.mdx | 412 ++++++++++++++++++ 2 files changed, 419 insertions(+) create mode 100644 src/content/docs/developer-spotlight/tutorials/fullstack-authentication-with-next-js-and-cloudflare-d1.mdx diff --git a/src/content/docs/developer-spotlight/index.mdx b/src/content/docs/developer-spotlight/index.mdx index 2ea8447cc068afb..dfdab1a0aeb365e 100644 --- a/src/content/docs/developer-spotlight/index.mdx +++ b/src/content/docs/developer-spotlight/index.mdx @@ -13,6 +13,13 @@ Applications are currently open until Thursday, the 24th of October 2024. To app ## View latest contributions + + By Mackenly Jones + + + +- Create a [Resend account](https://resend.com/signup). +- [Install and authenticate Wrangler](/workers/wrangler/install-and-update/). + +## 1. Create a Next.js app using Workers + +From within the repository or directory where you want to create your project run: + + + + + +This will create a new Next.js project using [OpenNext](https://opennext.js.org/cloudflare) that will run in a Worker using [Workers Assets](/workers/frameworks/framework-guides/nextjs/). + +Now, modify the newly created `package.json` slightly, adding `--ip localhost` to the preview command within the scripts like so: + +```json title="package.json" +"preview": "cloudflare && wrangler dev --ip localhost", +``` + +Throughout this tutorial, we'll add several values to Cloudflare Secrets. For [local development](/workers/configuration/secrets/#local-development-with-secrets), add those same values to a file in the top level of your project called `.dev.vars` and make sure it is not committed into version control. This will let you work with Secret values locally. Go ahead and copy and paste the following into `.dev.vars` for now and replace the values as we go. + +```sh title=".dev.vars" +AUTH_SECRET = "" +AUTH_RESEND_KEY = "" +AUTH_EMAIL_FROM = "" +AUTH_URL = "http://localhost:8787/" +``` + +:::note[Manually set URL] +Within the Workers environment, the `AUTH_URL` doesn't get picked up automatically by Auth.js, hence why we're specifying it manually here (we'll need to do the same for prod later). +::: + +## 2. Install Auth.js + +Following the [installation instructions](https://authjs.dev/getting-started/installation?framework=Next.js) from Auth.js, begin by installing Auth.js: + + + +Now run the following to generate an `AUTH_SECRET`: + +```sh +npx auth secret +``` + +Now, deviating from the standard Auth.js setup, locate your generated secret (likely in a file named `.env.local`) and [add the secret to your Workers application](/workers/configuration/secrets/#adding-secrets-to-your-project) by running the following and completing the steps to add a secret's value: + +```sh +npx wrangler secret put AUTH_SECRET +``` + +Next, go into the newly generated `env.d.ts` file and add the following to the interface: + +```ts title="env.d.ts" +interface CloudflareEnv { + AUTH_SECRET: string; +} +``` + +## 3. Install Cloudflare D1 Adapter + +Now, install the Auth.js D1 adapter by running: + + + +Create a D1 database using the following command: + +```sh title="Create D1 database" +npx wrangler d1 create auth-js-d1-example-db +``` + +When finished you should see instructions to add the database binding to your `wrangler.toml`. Example binding: + +```toml title="wrangler.toml" +[[d1_databases]] +binding = "DB" +database_name = "auth-js-d1-example-db" +database_id = "" +``` + +Now, within your `env.d.ts`, add your D1 binding, like: + +```ts title="env.d.ts" +interface CloudflareEnv { + DB: D1Database; + AUTH_SECRET: string; +} +``` + +## 4. Configure Credentials Provider + +Auth.js provides integrations for many different credential providers such as Google, GitHub, etc. For this tutorial we're going to use Resend magic links. + +Before continuing, either choose an alternative credential provider or ensure you have a domain and API key from Resend. + +With a domain [created and verified](https://resend.com/docs/dashboard/domains/introduction) within Resend, add a new Secret to your Worker containing an email from a verified domain such as `noreply@auth-js-d1-example.example.com`. + +```sh title="Add Resend email to secrets" +npx wrangler secret put AUTH_EMAIL_FROM +``` + +Now [create a Resend API key](https://resend.com/docs/dashboard/api-keys/introduction) with `Sending access` and add it to your Worker's Secrets: + +```sh title="Add Resend API key to secrets" +npx wrangler secret put AUTH_RESEND_KEY +``` + +After adding both of those Secrets, your `env.d.ts` should include the following: + +```ts title="env.d.ts" +interface CloudflareEnv { + DB: D1Database; + AUTH_SECRET: string; + AUTH_RESEND_KEY: string; + AUTH_EMAIL_FROM: string; +} +``` + +Credential providers and database adapters are provided to Auth.js through a configuration file called `auth.ts`. Create a file within your `src/app/` directory called `auth.ts` with the following contents: + + +```ts +import NextAuth from "next-auth"; +import { NextAuthResult } from "next-auth"; +import { D1Adapter } from "@auth/d1-adapter"; +import Resend from "next-auth/providers/resend"; + +const authResult = (): NextAuthResult => { +return NextAuth({ +providers: [ +Resend({ +apiKey: process.env.AUTH_RESEND_KEY, +from: process.env.AUTH_EMAIL_FROM, +}), +], +adapter: D1Adapter(process.env.DB), +}); +}; + +export const { handlers, signIn, signOut, auth } = authResult(); +``` + + +Now, lets add the route handler and middleware used to authenticate and persist sessions. + +Create a new directory structure and route handler within `src/app/api/auth/[...nextauth]` as `route.ts`. The file should contain: + + +```ts +import { handlers } from "../../../auth"; + +export const { GET, POST } = handlers; +``` + + +Now, within the `src/` directory, create a `middleware.ts` file to persist session data containing the following: + + +```ts +export { auth as middleware } from "./app/auth"; +``` + + +## 5. Create Database Tables + +The D1 adapter requires that tables be created within your database. It recommends using using the exported up() method to complete this. Within `src/app/api/` create a directory called `setup` containing a file called `route.ts`. Within this route handler, add the following code: + + +```ts +import type { NextRequest } from 'next/server'; +import { up } from "@auth/d1-adapter"; + +export async function GET(request: NextRequest) { + try { + await up(process.env.DB) + } catch (e: any) { + console.log(e.cause.message, e.message) + } + return new Response('Migration completed'); +} + +```` + + +You'll need to run this once on your production database to create the necessary tables. If you're following along with this tutorial, we'll run it together in a few steps. + +:::note[Clean up] +Running this multiple times won't hurt anything, but it's a good idea to remove this route from your production code once you've run it. +::: + +Before we go further, make sure you've created all of the necessary files: + +- src/ + - app/ + - api/ + - auth/ + - [...nextauth]/ + - route.ts + - setup/ + - route.ts + - auth.ts + - page.ts + - middleware.ts +- env.d.ts +- wrangler.toml + + +## 6. Build Sign-in Interface +We've completed the backend steps for our application. Now, we need a way to sign in. First, let's install shadcn: + + +Next, run the following to add a few components: +```sh title="Add components" +npx shadcn@latest add button input card avatar label +```` + +Replace the contents of `page.ts` from within the `app/` directory with the following: + +```ts title="src/app/page.ts" +import { redirect } from 'next/navigation'; +import { signIn, signOut, auth } from './auth'; +import { updateRecord } from '@auth/d1-adapter'; +import { Button } from '@/components/ui/button'; +import { Input } from '@/components/ui/input'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle, CardFooter } from '@/components/ui/card'; +import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'; +import { Label } from '@/components/ui/label'; + +async function updateName(formData: FormData): Promise { + 'use server'; + const session = await auth(); + if (!session?.user?.id) { + return; + } + const name = formData.get('name') as string; + if (!name) { + return; + } + const query = `UPDATE users SET name = $1 WHERE id = $2`; + await updateRecord(process.env.DB, query, [name, session.user.id]); + redirect('/'); +} + +export default async function Home() { + const session = await auth(); + return ( +
+ + + {session ? 'User Profile' : 'Login'} + + {session ? 'Manage your account' : 'Welcome to the auth-js-d1-example demo'} + + + + {session ? ( +
+
+ + + {session.user?.name?.[0] || 'U'} + +
+

{session.user?.name || 'No name set'}

+

{session.user?.email}

+
+
+
+

User ID: {session.user?.id}

+
+
+ + + +
+
+ ) : ( +
{ + 'use server'; + await signIn('resend', { email: formData.get('email') as string }); + }} + className="space-y-4" + > +
+ +
+ +
+ )} +
+ {session && ( + +
{ + 'use server'; + await signOut(); + Response.redirect('/'); + }} + > + +
+
+ )} +
+
+ ); +} +``` + +## 7. Preview and Deploy + +Now, it's time to preview our app. Run the following to preview your application: + +```sh title="Preview your application" +npm run preview +``` + +You should see our login form. But wait, we're not done yet. Remember to create your database tables by visiting `/api/setup`. You should see `Migration completed`. This means your database is ready to go. + +Navigate back to your application's homepage. Enter your email and sign in. You should receive an email in your inbox (check spam). Follow the link to sign in. If everything is configured correctly, you should now see a basic user profile letting your update your name and sign out. + +Now let's take our application to production. From within the project's directory run: + +```sh title="Deploy your application" +npm run deploy +``` + +This will build and deploy your application as a Worker. Note that you may need to select which account you want to deploy your Worker to. After your app is deployed, Wrangler should give you the URL on which it was deployed. It might look something like this: `https://auth-js-d1-example.example.workers.dev`. Add your URL to your Worker using: + +```sh title="Add URL to secrets" +npx wrangler secret put AUTH_URL +``` + +After the changes are deployed, you should now be able to access and try out your new application. + +You have successfully created, configured, and deployed a fullstack Next.js application with authentication powered by Auth.js, Resend, and Cloudflare D1. + +## Related resources + +To build more with Workers, refer to [Tutorials](/workers/tutorials/). + +Find more information about the tools and services used in this tutorial at: + +- [Auth.js](https://authjs.dev/getting-started) +- [Resend](https://resend.com/) +- [Cloudflare D1](/d1/) + +If you have any questions, need assistance, or would like to share your project, join the Cloudflare Developer community on [Discord](https://discord.cloudflare.com) to connect with other developers and the Cloudflare team. From ecd9815b2c5a1aa18f2c516765426a2a4975e3f6 Mon Sep 17 00:00:00 2001 From: Mackenly Jones <53151058+mackenly@users.noreply.github.com> Date: Sun, 10 Nov 2024 22:17:27 -0500 Subject: [PATCH 2/9] Style fixes --- ...ullstack-authentication-with-next-js-and-cloudflare-d1.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/content/docs/developer-spotlight/tutorials/fullstack-authentication-with-next-js-and-cloudflare-d1.mdx b/src/content/docs/developer-spotlight/tutorials/fullstack-authentication-with-next-js-and-cloudflare-d1.mdx index b8eb57d6131a6f5..b027ea5e7f442cd 100644 --- a/src/content/docs/developer-spotlight/tutorials/fullstack-authentication-with-next-js-and-cloudflare-d1.mdx +++ b/src/content/docs/developer-spotlight/tutorials/fullstack-authentication-with-next-js-and-cloudflare-d1.mdx @@ -25,7 +25,7 @@ import { In this tutorial, you will build a [Next.js app](/workers/frameworks/framework-guides/nextjs/) with authentication powered by Auth.js, Resend, and [Cloudflare D1](/d1/). -Before continuing, make sure you have a Cloudflare account and have installed and authenticated Wrangler. Some experience with HTML, CSS, and JavaScript/Typescript is helpful but not required. In this tutorial, you will learn: +Before continuing, make sure you have a Cloudflare account and have installed and authenticated Wrangler. Some experience with HTML, CSS, and JavaScript/TypeScript is helpful but not required. In this tutorial, you will learn: - How to create a Next.js application and run it on Cloudflare Workers - How to bind a Cloudflare D1 database to your Next.js app and use it to store authentication data @@ -212,7 +212,7 @@ export { auth as middleware } from "./app/auth"; ## 5. Create Database Tables -The D1 adapter requires that tables be created within your database. It recommends using using the exported up() method to complete this. Within `src/app/api/` create a directory called `setup` containing a file called `route.ts`. Within this route handler, add the following code: +The D1 adapter requires that tables be created within your database. It [recommends](https://authjs.dev/getting-started/adapters/d1#migrations) using the exported `up()` method to complete this. Within `src/app/api/` create a directory called `setup` containing a file called `route.ts`. Within this route handler, add the following code: ```ts From a4bc12b587f7ae6cdf19f87f0cbe07b917e4c525 Mon Sep 17 00:00:00 2001 From: Mackenly Jones <53151058+mackenly@users.noreply.github.com> Date: Tue, 3 Dec 2024 16:16:05 -0500 Subject: [PATCH 3/9] Adds auth link and fixes create args --- ...lstack-authentication-with-next-js-and-cloudflare-d1.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/content/docs/developer-spotlight/tutorials/fullstack-authentication-with-next-js-and-cloudflare-d1.mdx b/src/content/docs/developer-spotlight/tutorials/fullstack-authentication-with-next-js-and-cloudflare-d1.mdx index b027ea5e7f442cd..a6d521af8c1857a 100644 --- a/src/content/docs/developer-spotlight/tutorials/fullstack-authentication-with-next-js-and-cloudflare-d1.mdx +++ b/src/content/docs/developer-spotlight/tutorials/fullstack-authentication-with-next-js-and-cloudflare-d1.mdx @@ -25,7 +25,7 @@ import { In this tutorial, you will build a [Next.js app](/workers/frameworks/framework-guides/nextjs/) with authentication powered by Auth.js, Resend, and [Cloudflare D1](/d1/). -Before continuing, make sure you have a Cloudflare account and have installed and authenticated Wrangler. Some experience with HTML, CSS, and JavaScript/TypeScript is helpful but not required. In this tutorial, you will learn: +Before continuing, make sure you have a Cloudflare account and have installed and [authenticated Wrangler](https://developers.cloudflare.com/workers/wrangler/commands/#login). Some experience with HTML, CSS, and JavaScript/TypeScript is helpful but not required. In this tutorial, you will learn: - How to create a Next.js application and run it on Cloudflare Workers - How to bind a Cloudflare D1 database to your Next.js app and use it to store authentication data @@ -46,8 +46,8 @@ From within the repository or directory where you want to create your project ru Date: Tue, 3 Dec 2024 16:19:31 -0500 Subject: [PATCH 4/9] Moves args to args object for shadcn install --- .../fullstack-authentication-with-next-js-and-cloudflare-d1.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/developer-spotlight/tutorials/fullstack-authentication-with-next-js-and-cloudflare-d1.mdx b/src/content/docs/developer-spotlight/tutorials/fullstack-authentication-with-next-js-and-cloudflare-d1.mdx index a6d521af8c1857a..68b644a04a667f0 100644 --- a/src/content/docs/developer-spotlight/tutorials/fullstack-authentication-with-next-js-and-cloudflare-d1.mdx +++ b/src/content/docs/developer-spotlight/tutorials/fullstack-authentication-with-next-js-and-cloudflare-d1.mdx @@ -256,7 +256,7 @@ Before we go further, make sure you've created all of the necessary files: ## 6. Build Sign-in Interface We've completed the backend steps for our application. Now, we need a way to sign in. First, let's install shadcn: - + Next, run the following to add a few components: ```sh title="Add components" From 9b4a29b168fabdd9c6471d356dedfed48a7a0aeb Mon Sep 17 00:00:00 2001 From: Mackenly Jones <53151058+mackenly@users.noreply.github.com> Date: Tue, 3 Dec 2024 16:34:09 -0500 Subject: [PATCH 5/9] Refactor resend prereq --- ...lstack-authentication-with-next-js-and-cloudflare-d1.mdx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/content/docs/developer-spotlight/tutorials/fullstack-authentication-with-next-js-and-cloudflare-d1.mdx b/src/content/docs/developer-spotlight/tutorials/fullstack-authentication-with-next-js-and-cloudflare-d1.mdx index 68b644a04a667f0..bf5a291a11fc36f 100644 --- a/src/content/docs/developer-spotlight/tutorials/fullstack-authentication-with-next-js-and-cloudflare-d1.mdx +++ b/src/content/docs/developer-spotlight/tutorials/fullstack-authentication-with-next-js-and-cloudflare-d1.mdx @@ -37,7 +37,7 @@ You can find the finished code for this project on [GitHub](https://github.com/m -- Create a [Resend account](https://resend.com/signup). +- Create a [Resend account](https://resend.com/signup) with a [verified domain](https://resend.com/docs/dashboard/domains/introduction) and get an [API key](https://resend.com/docs/api-reference/api-keys/create-api-key). - [Install and authenticate Wrangler](/workers/wrangler/install-and-update/). ## 1. Create a Next.js app using Workers @@ -138,9 +138,7 @@ interface CloudflareEnv { ## 4. Configure Credentials Provider -Auth.js provides integrations for many different credential providers such as Google, GitHub, etc. For this tutorial we're going to use Resend magic links. - -Before continuing, either choose an alternative credential provider or ensure you have a domain and API key from Resend. +Auth.js provides integrations for many different [credential providers](https://authjs.dev/getting-started/authentication) such as Google, GitHub, etc. For this tutorial we're going to use [Resend for magic links](https://authjs.dev/getting-started/authentication/email). You should have already created a Resend account and have an API key. With a domain [created and verified](https://resend.com/docs/dashboard/domains/introduction) within Resend, add a new Secret to your Worker containing an email from a verified domain such as `noreply@auth-js-d1-example.example.com`. From 035159191dcb45a0c6ed65715b012fcb68b38eab Mon Sep 17 00:00:00 2001 From: Mackenly Jones <53151058+mackenly@users.noreply.github.com> Date: Tue, 3 Dec 2024 16:51:17 -0500 Subject: [PATCH 6/9] Removes unneeded localhost flag --- ...lstack-authentication-with-next-js-and-cloudflare-d1.mdx | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/content/docs/developer-spotlight/tutorials/fullstack-authentication-with-next-js-and-cloudflare-d1.mdx b/src/content/docs/developer-spotlight/tutorials/fullstack-authentication-with-next-js-and-cloudflare-d1.mdx index bf5a291a11fc36f..4e7bfda7e6e55f5 100644 --- a/src/content/docs/developer-spotlight/tutorials/fullstack-authentication-with-next-js-and-cloudflare-d1.mdx +++ b/src/content/docs/developer-spotlight/tutorials/fullstack-authentication-with-next-js-and-cloudflare-d1.mdx @@ -61,12 +61,6 @@ From within the repository or directory where you want to create your project ru This will create a new Next.js project using [OpenNext](https://opennext.js.org/cloudflare) that will run in a Worker using [Workers Assets](/workers/frameworks/framework-guides/nextjs/). -Now, modify the newly created `package.json` slightly, adding `--ip localhost` to the preview command within the scripts like so: - -```json title="package.json" -"preview": "cloudflare && wrangler dev --ip localhost", -``` - Throughout this tutorial, we'll add several values to Cloudflare Secrets. For [local development](/workers/configuration/secrets/#local-development-with-secrets), add those same values to a file in the top level of your project called `.dev.vars` and make sure it is not committed into version control. This will let you work with Secret values locally. Go ahead and copy and paste the following into `.dev.vars` for now and replace the values as we go. ```sh title=".dev.vars" From b19253d5a0408c4b3a450e0fbffed41d8a31f230 Mon Sep 17 00:00:00 2001 From: Mackenly Jones <53151058+mackenly@users.noreply.github.com> Date: Wed, 11 Dec 2024 13:33:39 -0500 Subject: [PATCH 7/9] Removes extra backticks --- ...ullstack-authentication-with-next-js-and-cloudflare-d1.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/content/docs/developer-spotlight/tutorials/fullstack-authentication-with-next-js-and-cloudflare-d1.mdx b/src/content/docs/developer-spotlight/tutorials/fullstack-authentication-with-next-js-and-cloudflare-d1.mdx index 4e7bfda7e6e55f5..c30dcc7772d80cf 100644 --- a/src/content/docs/developer-spotlight/tutorials/fullstack-authentication-with-next-js-and-cloudflare-d1.mdx +++ b/src/content/docs/developer-spotlight/tutorials/fullstack-authentication-with-next-js-and-cloudflare-d1.mdx @@ -220,7 +220,7 @@ export async function GET(request: NextRequest) { return new Response('Migration completed'); } -```` +``` You'll need to run this once on your production database to create the necessary tables. If you're following along with this tutorial, we'll run it together in a few steps. @@ -253,7 +253,7 @@ We've completed the backend steps for our application. Now, we need a way to sig Next, run the following to add a few components: ```sh title="Add components" npx shadcn@latest add button input card avatar label -```` +``` Replace the contents of `page.ts` from within the `app/` directory with the following: From e25473a1455780075e8bca2f612181a76961132c Mon Sep 17 00:00:00 2001 From: Mackenly Jones <53151058+mackenly@users.noreply.github.com> Date: Wed, 11 Dec 2024 13:51:11 -0500 Subject: [PATCH 8/9] Adds description to page code and swaps runs to use package manager agnostic component --- ...entication-with-next-js-and-cloudflare-d1.mdx | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/content/docs/developer-spotlight/tutorials/fullstack-authentication-with-next-js-and-cloudflare-d1.mdx b/src/content/docs/developer-spotlight/tutorials/fullstack-authentication-with-next-js-and-cloudflare-d1.mdx index c30dcc7772d80cf..89e8309e30aca6f 100644 --- a/src/content/docs/developer-spotlight/tutorials/fullstack-authentication-with-next-js-and-cloudflare-d1.mdx +++ b/src/content/docs/developer-spotlight/tutorials/fullstack-authentication-with-next-js-and-cloudflare-d1.mdx @@ -255,6 +255,8 @@ Next, run the following to add a few components: npx shadcn@latest add button input card avatar label ``` +To make it easy, we've provided a basic sign-in interface for you below that you can copy into your app. You will likely want to customize this to fit your needs, but for now, this will let you sign in, see your account details, and update your user's name. + Replace the contents of `page.ts` from within the `app/` directory with the following: ```ts title="src/app/page.ts" @@ -367,9 +369,10 @@ export default async function Home() { Now, it's time to preview our app. Run the following to preview your application: -```sh title="Preview your application" -npm run preview -``` + You should see our login form. But wait, we're not done yet. Remember to create your database tables by visiting `/api/setup`. You should see `Migration completed`. This means your database is ready to go. @@ -377,9 +380,10 @@ Navigate back to your application's homepage. Enter your email and sign in. You Now let's take our application to production. From within the project's directory run: -```sh title="Deploy your application" -npm run deploy -``` + This will build and deploy your application as a Worker. Note that you may need to select which account you want to deploy your Worker to. After your app is deployed, Wrangler should give you the URL on which it was deployed. It might look something like this: `https://auth-js-d1-example.example.workers.dev`. Add your URL to your Worker using: From 409cd1d2068db5997df744621e438f7bc97d539c Mon Sep 17 00:00:00 2001 From: Mackenly Jones <53151058+mackenly@users.noreply.github.com> Date: Wed, 11 Dec 2024 14:33:49 -0500 Subject: [PATCH 9/9] Fix env access to use cloudflare context --- ...ication-with-next-js-and-cloudflare-d1.mdx | 33 ++++++++++--------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/src/content/docs/developer-spotlight/tutorials/fullstack-authentication-with-next-js-and-cloudflare-d1.mdx b/src/content/docs/developer-spotlight/tutorials/fullstack-authentication-with-next-js-and-cloudflare-d1.mdx index 89e8309e30aca6f..0e0eaf97d9ce394 100644 --- a/src/content/docs/developer-spotlight/tutorials/fullstack-authentication-with-next-js-and-cloudflare-d1.mdx +++ b/src/content/docs/developer-spotlight/tutorials/fullstack-authentication-with-next-js-and-cloudflare-d1.mdx @@ -165,20 +165,21 @@ import NextAuth from "next-auth"; import { NextAuthResult } from "next-auth"; import { D1Adapter } from "@auth/d1-adapter"; import Resend from "next-auth/providers/resend"; - -const authResult = (): NextAuthResult => { -return NextAuth({ -providers: [ -Resend({ -apiKey: process.env.AUTH_RESEND_KEY, -from: process.env.AUTH_EMAIL_FROM, -}), -], -adapter: D1Adapter(process.env.DB), -}); +import { getCloudflareContext } from "@opennextjs/cloudflare"; + +const authResult = async (): Promise => { + return NextAuth({ + providers: [ + Resend({ + apiKey: (await getCloudflareContext()).env.AUTH_RESEND_KEY, + from: (await getCloudflareContext()).env.AUTH_EMAIL_FROM, + }), + ], + adapter: D1Adapter((await getCloudflareContext()).env.DB), + }); }; -export const { handlers, signIn, signOut, auth } = authResult(); +export const { handlers, signIn, signOut, auth } = await authResult(); ``` @@ -210,10 +211,11 @@ The D1 adapter requires that tables be created within your database. It [recomme ```ts import type { NextRequest } from 'next/server'; import { up } from "@auth/d1-adapter"; +import { getCloudflareContext } from "@opennextjs/cloudflare"; export async function GET(request: NextRequest) { try { - await up(process.env.DB) + await up((await getCloudflareContext()).env.DB) } catch (e: any) { console.log(e.cause.message, e.message) } @@ -226,7 +228,7 @@ export async function GET(request: NextRequest) { You'll need to run this once on your production database to create the necessary tables. If you're following along with this tutorial, we'll run it together in a few steps. :::note[Clean up] -Running this multiple times won't hurt anything, but it's a good idea to remove this route from your production code once you've run it. +Running this multiple times won't hurt anything since the tables are only created if they do not already exist, but it's a good idea to remove this route from your production code once you've run it. ::: Before we go further, make sure you've created all of the necessary files: @@ -263,6 +265,7 @@ Replace the contents of `page.ts` from within the `app/` directory with the foll import { redirect } from 'next/navigation'; import { signIn, signOut, auth } from './auth'; import { updateRecord } from '@auth/d1-adapter'; +import { getCloudflareContext } from '@opennextjs/cloudflare'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Card, CardContent, CardDescription, CardHeader, CardTitle, CardFooter } from '@/components/ui/card'; @@ -280,7 +283,7 @@ async function updateName(formData: FormData): Promise { return; } const query = `UPDATE users SET name = $1 WHERE id = $2`; - await updateRecord(process.env.DB, query, [name, session.user.id]); + await updateRecord((await getCloudflareContext()).env.DB, query, [name, session.user.id]); redirect('/'); }