mirror of
https://github.com/LukeHagar/better-auth.git
synced 2025-12-06 20:37:44 +00:00
docs: nitro Integration (#694)
This commit is contained in:
@@ -434,4 +434,58 @@ export const Icons = {
|
|||||||
<path d="M100.28 448H7.4V148.9h92.88zM53.79 108.1C24.09 108.1 0 83.5 0 53.8a53.79 53.79 0 0 1 107.58 0c0 29.7-24.1 54.3-53.79 54.3zM447.9 448h-92.68V302.4c0-34.7-.7-79.2-48.29-79.2-48.29 0-55.69 37.7-55.69 76.7V448h-92.78V148.9h89.08v40.8h1.3c12.4-23.5 42.69-48.3 87.88-48.3 94 0 111.28 61.9 111.28 142.3V448z"></path>
|
<path d="M100.28 448H7.4V148.9h92.88zM53.79 108.1C24.09 108.1 0 83.5 0 53.8a53.79 53.79 0 0 1 107.58 0c0 29.7-24.1 54.3-53.79 54.3zM447.9 448h-92.68V302.4c0-34.7-.7-79.2-48.29-79.2-48.29 0-55.69 37.7-55.69 76.7V448h-92.78V148.9h89.08v40.8h1.3c12.4-23.5 42.69-48.3 87.88-48.3 94 0 111.28 61.9 111.28 142.3V448z"></path>
|
||||||
</svg>
|
</svg>
|
||||||
),
|
),
|
||||||
|
nitro: (props?: SVGProps<any>) => (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="currentColor" // Use currentColor here
|
||||||
|
className="w-full h-full"
|
||||||
|
viewBox="0 0 40 40"
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<g clipPath="url(#a)">
|
||||||
|
<path
|
||||||
|
fill="currentColor" // Use currentColor here
|
||||||
|
fillRule="evenodd"
|
||||||
|
d="M35.217 7.02C28.047-1.383 15.424-2.384 7.02 4.785c-8.404 7.169-9.404 19.792-2.236 28.196 7.17 8.403 19.793 9.404 28.196 2.235 8.404-7.169 9.404-19.793 2.236-28.196Zm-9.964 10.497c.77 0 1.262.836.876 1.502l-.112.192L18.47 31.63a.773.773 0 0 1-.661.372h-.72a.755.755 0 0 1-.732-.944l2.048-7.919a1 1 0 0 0-.968-1.25h-3.146a1 1 0 0 1-.968-1.25l3.09-11.955a.923.923 0 0 1 .895-.68c.05 0 .097 0 .135.002h3.168a1 1 0 0 1 .991 1.134l-.02.143-1.207 7.067a1 1 0 0 0 .985 1.168h3.893Z"
|
||||||
|
clipRule="evenodd"
|
||||||
|
/>
|
||||||
|
<mask
|
||||||
|
id="d"
|
||||||
|
x={0}
|
||||||
|
y={0}
|
||||||
|
maskUnits="userSpaceOnUse"
|
||||||
|
style={{
|
||||||
|
maskType: "alpha",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<circle cx={20} cy={20.001} r={20} fill="currentColor" />
|
||||||
|
</mask>
|
||||||
|
<g filter="url(#e)" mask="url(#d)">
|
||||||
|
<path
|
||||||
|
fill="currentColor" // Use currentColor here
|
||||||
|
d="M1.111 13.427a20 20 0 1 0 37.957.541l-5.815 1.84a13.901 13.901 0 1 1-26.381-.376l-5.76-2.005Z"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<clipPath id="a">
|
||||||
|
<path fill="#fff" d="M0 0h146v40.001H0z" />
|
||||||
|
</clipPath>
|
||||||
|
<filter
|
||||||
|
id="e"
|
||||||
|
x={-10}
|
||||||
|
y={3.427}
|
||||||
|
colorInterpolationFilters="sRGB"
|
||||||
|
filterUnits="userSpaceOnUse"
|
||||||
|
>
|
||||||
|
<feFlood floodOpacity={0} result="BackgroundImageFix" />
|
||||||
|
<feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
|
||||||
|
<feGaussianBlur
|
||||||
|
result="effect1_foregroundBlur_115_108"
|
||||||
|
stdDeviation={5}
|
||||||
|
/>
|
||||||
|
</filter>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -702,6 +702,11 @@ export const contents: Content[] = [
|
|||||||
icon: Icons.elysia,
|
icon: Icons.elysia,
|
||||||
href: "/docs/integrations/elysia",
|
href: "/docs/integrations/elysia",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: "Nitro",
|
||||||
|
icon: Icons.nitro,
|
||||||
|
href: "/docs/integrations/nitro",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
group: true,
|
group: true,
|
||||||
title: "Mobile & Desktop",
|
title: "Mobile & Desktop",
|
||||||
|
|||||||
@@ -42,4 +42,8 @@ export const techStackIcons: TechStackIconType = {
|
|||||||
name: "Expo",
|
name: "Expo",
|
||||||
icon: <Icons.expo className="w-10 h-10" />,
|
icon: <Icons.expo className="w-10 h-10" />,
|
||||||
},
|
},
|
||||||
|
nitro: {
|
||||||
|
name: "Nitro",
|
||||||
|
icon: <Icons.nitro className="w-10 h-10" />,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
197
docs/content/docs/integrations/nitro.mdx
Normal file
197
docs/content/docs/integrations/nitro.mdx
Normal file
@@ -0,0 +1,197 @@
|
|||||||
|
---
|
||||||
|
title: Nitro Integration
|
||||||
|
description: Integrate Better Auth with Nitro.
|
||||||
|
---
|
||||||
|
|
||||||
|
Better Auth can be integrated with your [Nitro Application](https://nitro.build/)(an open source framework to build web servers).
|
||||||
|
|
||||||
|
This guide aims to help you integrate Better Auth with your Nitro application in a few simple steps.
|
||||||
|
|
||||||
|
## Create a new Nitro Application
|
||||||
|
|
||||||
|
Start by scaffolding a new Nitro application using the following command:
|
||||||
|
|
||||||
|
```bash title="Terminal"
|
||||||
|
npx giget@latest nitro nitro-app --install
|
||||||
|
```
|
||||||
|
|
||||||
|
This will create the `nitro-app` directory and install all the dependencies. You can now open the `nitro-app` directory in your code editor.
|
||||||
|
|
||||||
|
### Prisma Adapter Setup
|
||||||
|
|
||||||
|
<Callout>
|
||||||
|
This guide assumes that you have a basic understanding of Prisma. If you are new to Prisma, you can check out the [Prisma documentation](https://www.prisma.io/docs/getting-started).
|
||||||
|
|
||||||
|
The `sqlite` database used in this guide will not work in a production environment. You should replace it with a production-ready database like `PostgreSQL`.
|
||||||
|
</Callout>
|
||||||
|
|
||||||
|
For this guide, we will be using the Prisma adapter. You can install prisma client by running the following command:
|
||||||
|
|
||||||
|
```package-install
|
||||||
|
@prisma/client
|
||||||
|
```
|
||||||
|
|
||||||
|
`prisma` can be installed as a dev dependency using the following command:
|
||||||
|
|
||||||
|
```package-install
|
||||||
|
-D prisma
|
||||||
|
```
|
||||||
|
|
||||||
|
Generate a `schema.prisma` file in the `prisma` directory by running the following command:
|
||||||
|
|
||||||
|
```bash title="Terminal"
|
||||||
|
npx prisma init
|
||||||
|
```
|
||||||
|
|
||||||
|
You can now replace the contents of the `schema.prisma` file with the following:
|
||||||
|
|
||||||
|
```prisma title="prisma/schema.prisma"
|
||||||
|
generator client {
|
||||||
|
provider = "prisma-client-js"
|
||||||
|
}
|
||||||
|
|
||||||
|
datasource db {
|
||||||
|
provider = "sqlite"
|
||||||
|
url = env("DATABASE_URL")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Will be deleted. Just need it to generate the prisma client
|
||||||
|
model Test {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
name String
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Ensure that you update the `DATABASE_URL` in your `.env` file to point to the location of your database.
|
||||||
|
|
||||||
|
```env title=".env"
|
||||||
|
DATABASE_URL="file:./dev.db"
|
||||||
|
```
|
||||||
|
|
||||||
|
Run the following command to generate the Prisma client & sync the database:
|
||||||
|
|
||||||
|
```bash title="Terminal"
|
||||||
|
npx prisma db push
|
||||||
|
```
|
||||||
|
|
||||||
|
### Install & Configure Better Auth
|
||||||
|
|
||||||
|
Follow steps 1 & 2 from the [installation guide](/docs/installation) to install Better Auth in your Nitro application & set up the environment variables.
|
||||||
|
|
||||||
|
Once that is done, create your better auth instance within the `server/utils/auth.ts` file.
|
||||||
|
|
||||||
|
```ts title="server/utils/auth.ts"
|
||||||
|
import { betterAuth } from "better-auth";
|
||||||
|
import { prismaAdapter } from "better-auth/adapters/prisma";
|
||||||
|
import { PrismaClient } from "@prisma/client";
|
||||||
|
|
||||||
|
const prisma = new PrismaClient();
|
||||||
|
export const auth = betterAuth({
|
||||||
|
database: prismaAdapter(prisma, { provider: "sqlite" }),
|
||||||
|
emailAndPassword: { enabled: true },
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Update Prisma Schema
|
||||||
|
|
||||||
|
Use the Better Auth CLI to update your Prisma schema with the required models by running the following command:
|
||||||
|
|
||||||
|
```bash title="Terminal"
|
||||||
|
npx @better-auth/cli generate --config server/utils/auth.ts
|
||||||
|
```
|
||||||
|
|
||||||
|
<Callout>
|
||||||
|
The `--config` flag is used to specify the path to the file where you have created your Better Auth instance.
|
||||||
|
</Callout>
|
||||||
|
|
||||||
|
Head over to the `prisma/schema.prisma` file & save the file to trigger the format on save.
|
||||||
|
|
||||||
|
After saving the file, you can run the `npx prisma db push` command to update the database schema.
|
||||||
|
|
||||||
|
## Mount The Handler
|
||||||
|
|
||||||
|
You can now mount the Better Auth handler in your Nitro application. You can do this by adding the following code to your `server/routes/api/auth/[...all].ts` file:
|
||||||
|
|
||||||
|
```ts title="server/routes/api/auth/[...all].ts"
|
||||||
|
export default defineEventHandler((event) => {
|
||||||
|
return auth.handler(toWebRequest(event));
|
||||||
|
});
|
||||||
|
```
|
||||||
|
<Callout>
|
||||||
|
This is a [catch-all](https://nitro.build/guide/routing#catch-all-route) route that will handle all requests to `/api/auth/*`.
|
||||||
|
</Callout>
|
||||||
|
|
||||||
|
### Cors
|
||||||
|
|
||||||
|
You can configure CORS for your Nitro app by creating a plugin.
|
||||||
|
|
||||||
|
Start by installing the cors package:
|
||||||
|
|
||||||
|
```package-install
|
||||||
|
cors
|
||||||
|
```
|
||||||
|
|
||||||
|
You can now create a new file `server/plugins/cors.ts` and add the following code:
|
||||||
|
|
||||||
|
```ts title="server/plugins/cors.ts"
|
||||||
|
import cors from "cors";
|
||||||
|
export default defineNitroPlugin((plugin) => {
|
||||||
|
plugin.h3App.use(
|
||||||
|
fromNodeMiddleware(
|
||||||
|
cors({
|
||||||
|
origin: "*",
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
<Callout>
|
||||||
|
This will enable CORS for all routes. You can customize the `origin` property to allow requests from specific domains. Ensure that the config is in sync with your frontend application.
|
||||||
|
</Callout>
|
||||||
|
|
||||||
|
### Auth Guard/Middleware
|
||||||
|
|
||||||
|
You can add an auth guard to your Nitro application to protect routes that require authentication. You can do this by creating a new file `server/utils/require-auth.ts` and adding the following code:
|
||||||
|
|
||||||
|
```ts title="server/utils/require-auth.ts"
|
||||||
|
import { EventHandler, H3Event } from "h3";
|
||||||
|
import { fromNodeHeaders } from "better-auth/node";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Middleware used to require authentication for a route.
|
||||||
|
*
|
||||||
|
* Can be extended to check for specific roles or permissions.
|
||||||
|
*/
|
||||||
|
export const requireAuth: EventHandler = async (event: H3Event) => {
|
||||||
|
const headers = getRequestHeaders(event);
|
||||||
|
|
||||||
|
const session = await auth.api.getSession({
|
||||||
|
headers: fromNodeHeaders(headers),
|
||||||
|
});
|
||||||
|
if (!session)
|
||||||
|
throw createError({
|
||||||
|
statusCode: 401,
|
||||||
|
statusMessage: "Unauthorized",
|
||||||
|
});
|
||||||
|
// You can save the session to the event context for later use
|
||||||
|
event.context.auth = session;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
You can now use this event handler/middleware in your routes to protect them:
|
||||||
|
|
||||||
|
```ts title="server/routes/api/secret.get.ts"
|
||||||
|
// Object syntax of the route handler
|
||||||
|
export default defineEventHandler({
|
||||||
|
// The user has to be logged in to access this route
|
||||||
|
onRequest: [requireAuth],
|
||||||
|
handler: async (event) => {
|
||||||
|
setResponseStatus(event, 201, "Secret data");
|
||||||
|
return { message: "Secret data" };
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
You can find an example of a Nitro application integrated with Better Auth & Prisma [here](https://github.com/BayBreezy/nitrojs-better-auth-prisma).
|
||||||
Reference in New Issue
Block a user