mirror of
https://github.com/SrIzan10/next-auth.git
synced 2026-05-01 10:55:20 +00:00
docs: fix sidebar, remove duplicates
This commit is contained in:
@@ -1,147 +0,0 @@
|
||||
---
|
||||
id: dynamodb
|
||||
title: DynamoDB
|
||||
---
|
||||
|
||||
# DynamoDB
|
||||
|
||||
This is the AWS DynamoDB Adapter for next-auth. This package can only be used in conjunction with the primary next-auth package. It is not a standalone package.
|
||||
|
||||
By default, the adapter expects a table with a partition key `pk` and a sort key `sk`, as well as a global secondary index named `GSI1` with `GSI1PK` as partition key and `GSI1SK` as sorting key. To automatically delete sessions and verification requests after they expire using [dynamodb TTL](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/TTL.html) you should [enable the TTL](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/time-to-live-ttl-how-to.html) with attribute name 'expires'. You can set whatever you want as the table name and the billing method.
|
||||
|
||||
You can find the full schema in the table structure section below.
|
||||
|
||||
## Getting Started
|
||||
|
||||
1. Install `next-auth` and `@next-auth/dynamodb-adapter`
|
||||
|
||||
```bash npm2yarn2pnpm
|
||||
npm install next-auth @next-auth/dynamodb-adapter
|
||||
```
|
||||
|
||||
2. Add this adapter to your `pages/api/auth/[...nextauth].js` next-auth configuration object.
|
||||
|
||||
You need to pass `DynamoDBDocument` client from the modular [`aws-sdk`](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/dynamodb-example-dynamodb-utilities.html) v3 to the adapter.
|
||||
The default table name is `next-auth`, but you can customise that by passing `{ tableName: 'your-table-name' }` as the second parameter in the adapter.
|
||||
|
||||
```javascript title="pages/api/auth/[...nextauth].js"
|
||||
import { DynamoDB } from "@aws-sdk/client-dynamodb"
|
||||
import { DynamoDBDocument } from "@aws-sdk/lib-dynamodb"
|
||||
import NextAuth from "next-auth";
|
||||
import Providers from "next-auth/providers";
|
||||
import { DynamoDBAdapter } from "@next-auth/dynamodb-adapter"
|
||||
|
||||
const config: DynamoDBClientConfig = {
|
||||
credentials: {
|
||||
accessKeyId: process.env.NEXT_AUTH_AWS_ACCESS_KEY as string,
|
||||
secretAccessKey: process.env.NEXT_AUTH_AWS_SECRET_KEY as string,
|
||||
},
|
||||
region: process.env.NEXT_AUTH_AWS_REGION,
|
||||
};
|
||||
|
||||
const client = DynamoDBDocument.from(new DynamoDB(config), {
|
||||
marshallOptions: {
|
||||
convertEmptyValues: true,
|
||||
removeUndefinedValues: true,
|
||||
convertClassInstanceToMap: true,
|
||||
},
|
||||
})
|
||||
|
||||
export default NextAuth({
|
||||
// Configure one or more authentication providers
|
||||
providers: [
|
||||
Providers.GitHub({
|
||||
clientId: process.env.GITHUB_ID,
|
||||
clientSecret: process.env.GITHUB_SECRET,
|
||||
}),
|
||||
Providers.Email({
|
||||
server: process.env.EMAIL_SERVER,
|
||||
from: process.env.EMAIL_FROM,
|
||||
}),
|
||||
// ...add more providers here
|
||||
],
|
||||
adapter: DynamoDBAdapter(
|
||||
client
|
||||
),
|
||||
...
|
||||
});
|
||||
```
|
||||
|
||||
(AWS secrets start with `NEXT_AUTH_` in order to not conflict with [Vercel's reserved environment variables](https://vercel.com/docs/environment-variables#reserved-environment-variables).)
|
||||
|
||||
## Schema
|
||||
|
||||
The table respects the single table design pattern. This has many advantages:
|
||||
|
||||
- Only one table to manage, monitor and provision.
|
||||
- Querying relations is faster than with multi-table schemas (for eg. retrieving all sessions for a user).
|
||||
- Only one table needs to be replicated, if you want to go multi-region.
|
||||
|
||||
> This schema is adapted for use in DynamoDB and based upon our main [schema](/adapters/models)
|
||||
|
||||

|
||||
|
||||
You can create this table with infrastructure as code using [`aws-cdk`](https://github.com/aws/aws-cdk) with the following table definition:
|
||||
|
||||
```javascript title=stack.ts
|
||||
new dynamodb.Table(this, `NextAuthTable`, {
|
||||
tableName: "next-auth",
|
||||
partitionKey: { name: "pk", type: dynamodb.AttributeType.STRING },
|
||||
sortKey: { name: "sk", type: dynamodb.AttributeType.STRING },
|
||||
timeToLiveAttribute: "expires",
|
||||
}).addGlobalSecondaryIndex({
|
||||
indexName: "GSI1",
|
||||
partitionKey: { name: "GSI1PK", type: dynamodb.AttributeType.STRING },
|
||||
sortKey: { name: "GSI1SK", type: dynamodb.AttributeType.STRING },
|
||||
})
|
||||
```
|
||||
|
||||
Alternatively you can use this cloudformation template:
|
||||
|
||||
```yaml title=cloudformation.yaml
|
||||
NextAuthTable:
|
||||
Type: "AWS::DynamoDB::Table"
|
||||
Properties:
|
||||
TableName: next-auth
|
||||
AttributeDefinitions:
|
||||
- AttributeName: pk
|
||||
AttributeType: S
|
||||
- AttributeName: sk
|
||||
AttributeType: S
|
||||
- AttributeName: GSI1PK
|
||||
AttributeType: S
|
||||
- AttributeName: GSI1SK
|
||||
AttributeType: S
|
||||
KeySchema:
|
||||
- AttributeName: pk
|
||||
KeyType: HASH
|
||||
- AttributeName: sk
|
||||
KeyType: RANGE
|
||||
GlobalSecondaryIndexes:
|
||||
- IndexName: GSI1
|
||||
Projection:
|
||||
ProjectionType: ALL
|
||||
KeySchema:
|
||||
- AttributeName: GSI1PK
|
||||
KeyType: HASH
|
||||
- AttributeName: GSI1SK
|
||||
KeyType: RANGE
|
||||
TimeToLiveSpecification:
|
||||
AttributeName: expires
|
||||
Enabled: true
|
||||
```
|
||||
|
||||
## Custom Schema
|
||||
|
||||
You can configure your custom table schema by passing the `options` key to the adapter constructor:
|
||||
|
||||
```
|
||||
const adapter = DynamoDBAdapter(client, {
|
||||
tableName: "custom-table-name",
|
||||
partitionKey: "custom-pk",
|
||||
sortKey: "custom-sk",
|
||||
indexName: "custom-index-name",
|
||||
indexPartitionKey: "custom-index-pk",
|
||||
indexSortKey: "custom-index-sk",
|
||||
})
|
||||
```
|
||||
@@ -1,85 +0,0 @@
|
||||
---
|
||||
id: fauna
|
||||
title: FaunaDB
|
||||
---
|
||||
|
||||
# FaunaDB
|
||||
|
||||
This is the Fauna Adapter for [`next-auth`](https://next-auth.js.org). This package can only be used in conjunction with the primary `next-auth` package. It is not a standalone package.
|
||||
|
||||
You can find the Fauna schema and seed information in the docs at [next-auth.js.org/adapters/fauna](https://next-auth.js.org/adapters/fauna).
|
||||
|
||||
## Getting Started
|
||||
|
||||
1. Install the necessary packages
|
||||
|
||||
```bash npm2yarn2pnpm
|
||||
npm install next-auth @next-auth/fauna-adapter faunadb
|
||||
```
|
||||
|
||||
2. Add this adapter to your `pages/api/auth/[...nextauth].js` next-auth configuration object.
|
||||
|
||||
```javascript title="pages/api/auth/[...nextauth].js"
|
||||
import NextAuth from "next-auth"
|
||||
import { Client as FaunaClient } from "faunadb"
|
||||
import { FaunaAdapter } from "@next-auth/fauna-adapter"
|
||||
|
||||
const client = new FaunaClient({
|
||||
secret: "secret",
|
||||
scheme: "http",
|
||||
domain: "localhost",
|
||||
port: 8443,
|
||||
})
|
||||
|
||||
// For more information on each option (and a full list of options) go to
|
||||
// https://next-auth.js.org/configuration/options
|
||||
export default NextAuth({
|
||||
// https://next-auth.js.org/providers/overview
|
||||
providers: [],
|
||||
adapter: FaunaAdapter(client)
|
||||
...
|
||||
})
|
||||
```
|
||||
|
||||
## Schema
|
||||
|
||||
Run the following commands inside of the `Shell` tab in the Fauna dashboard to setup the appropriate collections and indexes.
|
||||
|
||||
```javascript
|
||||
CreateCollection({ name: "accounts" })
|
||||
CreateCollection({ name: "sessions" })
|
||||
CreateCollection({ name: "users" })
|
||||
CreateCollection({ name: "verification_tokens" })
|
||||
```
|
||||
|
||||
```javascript
|
||||
CreateIndex({
|
||||
name: "account_by_provider_and_provider_account_id",
|
||||
source: Collection("accounts"),
|
||||
unique: true,
|
||||
terms: [
|
||||
{ field: ["data", "provider"] },
|
||||
{ field: ["data", "providerAccountId"] },
|
||||
],
|
||||
})
|
||||
CreateIndex({
|
||||
name: "session_by_session_token",
|
||||
source: Collection("sessions"),
|
||||
unique: true,
|
||||
terms: [{ field: ["data", "sessionToken"] }],
|
||||
})
|
||||
CreateIndex({
|
||||
name: "user_by_email",
|
||||
source: Collection("users"),
|
||||
unique: true,
|
||||
terms: [{ field: ["data", "email"] }],
|
||||
})
|
||||
CreateIndex({
|
||||
name: "verification_token_by_identifier_and_token",
|
||||
source: Collection("verification_tokens"),
|
||||
unique: true,
|
||||
terms: [{ field: ["data", "identifier"] }, { field: ["data", "token"] }],
|
||||
})
|
||||
```
|
||||
|
||||
> This schema is adapted for use in Fauna and based upon our main [schema](/adapters/models)
|
||||
@@ -1,66 +0,0 @@
|
||||
---
|
||||
id: mongodb
|
||||
title: MongoDB
|
||||
---
|
||||
|
||||
# MongoDB
|
||||
|
||||
The MongoDB adapter does not handle connections automatically, so you will have to make sure that you pass the Adapter a `MongoClient` that is connected already. Below you can see an example how to do this.
|
||||
|
||||
## Usage
|
||||
|
||||
1. Install the necessary packages
|
||||
|
||||
```bash npm2yarn2pnpm
|
||||
npm install next-auth @next-auth/mongodb-adapter mongodb
|
||||
```
|
||||
|
||||
2. Add `lib/mongodb.ts`
|
||||
|
||||
```ts
|
||||
// This approach is taken from https://github.com/vercel/next.js/tree/canary/examples/with-mongodb
|
||||
import { MongoClient } from 'mongodb'
|
||||
|
||||
if (!process.env.MONGODB_URI) {
|
||||
throw new Error('Invalid/Missing environment variable: "MONGODB_URI"')
|
||||
}
|
||||
|
||||
const uri = process.env.MONGODB_URI
|
||||
const options = {}
|
||||
|
||||
let client
|
||||
let clientPromise: Promise<MongoClient>
|
||||
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
// In development mode, use a global variable so that the value
|
||||
// is preserved across module reloads caused by HMR (Hot Module Replacement).
|
||||
if (!global._mongoClientPromise) {
|
||||
client = new MongoClient(uri, options)
|
||||
global._mongoClientPromise = client.connect()
|
||||
}
|
||||
clientPromise = global._mongoClientPromise
|
||||
} else {
|
||||
// In production mode, it's best to not use a global variable.
|
||||
client = new MongoClient(uri, options)
|
||||
clientPromise = client.connect()
|
||||
}
|
||||
|
||||
// Export a module-scoped MongoClient promise. By doing this in a
|
||||
// separate module, the client can be shared across functions.
|
||||
export default clientPromise
|
||||
```
|
||||
|
||||
3. Add this adapter to your `pages/api/auth/[...nextauth].js` next-auth configuration object.
|
||||
|
||||
```js
|
||||
import NextAuth from "next-auth"
|
||||
import { MongoDBAdapter } from "@next-auth/mongodb-adapter"
|
||||
import clientPromise from "../../../lib/mongodb"
|
||||
|
||||
// For more information on each option (and a full list of options) go to
|
||||
// https://next-auth.js.org/configuration/options
|
||||
export default NextAuth({
|
||||
adapter: MongoDBAdapter(clientPromise),
|
||||
...
|
||||
})
|
||||
```
|
||||
@@ -1,237 +0,0 @@
|
||||
---
|
||||
id: typeorm
|
||||
title: TypeORM
|
||||
---
|
||||
|
||||
# TypeORM
|
||||
|
||||
This Adapter is used to support SQL-flavored databases (like SQLite, MySQL, MSSQL, MariaDB, CockroachDB, etc.) through [TypeORM](https://typeorm.io).
|
||||
|
||||
:::note
|
||||
If you previously used this Adapter with MongoDB, check out the [MongoDB Adapter](/adapters/mongodb) instead.
|
||||
:::
|
||||
|
||||
:::note
|
||||
In the future, we might split up this adapter to support single flavors of SQL for easier maintenance and reduced bundle size.
|
||||
:::
|
||||
|
||||
## Usage
|
||||
|
||||
:::warning
|
||||
[`typeorm`](https://github.com/typeorm/typeorm) is still in active development and has not yet published a stable release. Because of this, you can expect breaking changes in minor versions. This adapter expects `typeorm@0.3.7` and is not validated against previous or future releases.
|
||||
:::
|
||||
|
||||
To use this Adapter, you need to install the following packages:
|
||||
|
||||
```bash npm2yarn2pnpm
|
||||
npm install next-auth @next-auth/typeorm-legacy-adapter typeorm
|
||||
```
|
||||
|
||||
Configure your NextAuth.js to use the TypeORM Adapter:
|
||||
|
||||
```javascript title="pages/api/auth/[...nextauth].js"
|
||||
import NextAuth from "next-auth"
|
||||
import { TypeORMLegacyAdapter } from "@next-auth/typeorm-legacy-adapter"
|
||||
|
||||
|
||||
export default NextAuth({
|
||||
adapter: TypeORMLegacyAdapter("yourconnectionstring"),
|
||||
...
|
||||
})
|
||||
```
|
||||
|
||||
`TypeORMLegacyAdapter` takes either a connection string, or a [`DataSourceOptions`](https://github.com/typeorm/typeorm/blob/master/docs/data-source-options.md) object as its first parameter.
|
||||
|
||||
## Custom models
|
||||
|
||||
The TypeORM adapter uses [`Entity` classes](https://github.com/typeorm/typeorm/blob/master/docs/entities.md) to define the shape of your data.
|
||||
|
||||
If you want to override the default entities (for example to add a `role` field to your `UserEntity`), you will have to do the following:
|
||||
|
||||
> This schema is adapted for use in TypeORM and based upon our main [schema](/adapters/models)
|
||||
|
||||
1. Create a file containing your modified entities:
|
||||
|
||||
(The file below is based on the [default entities](https://github.com/nextauthjs/next-auth/blob/main/packages/adapter-typeorm-legacy/src/entities.ts))
|
||||
|
||||
```diff title="lib/entities.ts"
|
||||
import {
|
||||
Entity,
|
||||
PrimaryGeneratedColumn,
|
||||
Column,
|
||||
ManyToOne,
|
||||
OneToMany,
|
||||
ValueTransformer,
|
||||
} from "typeorm"
|
||||
|
||||
const transformer: Record<"date" | "bigint", ValueTransformer> = {
|
||||
date: {
|
||||
from: (date: string | null) => date && new Date(parseInt(date, 10)),
|
||||
to: (date?: Date) => date?.valueOf().toString(),
|
||||
},
|
||||
bigint: {
|
||||
from: (bigInt: string | null) => bigInt && parseInt(bigInt, 10),
|
||||
to: (bigInt?: number) => bigInt?.toString(),
|
||||
},
|
||||
}
|
||||
|
||||
@Entity({ name: "users" })
|
||||
export class UserEntity {
|
||||
@PrimaryGeneratedColumn("uuid")
|
||||
id!: string
|
||||
|
||||
@Column({ type: "varchar", nullable: true })
|
||||
name!: string | null
|
||||
|
||||
@Column({ type: "varchar", nullable: true, unique: true })
|
||||
email!: string | null
|
||||
|
||||
@Column({ type: "varchar", nullable: true, transformer: transformer.date })
|
||||
emailVerified!: string | null
|
||||
|
||||
@Column({ type: "varchar", nullable: true })
|
||||
image!: string | null
|
||||
|
||||
+ @Column({ type: "varchar", nullable: true })
|
||||
+ role!: string | null
|
||||
|
||||
@OneToMany(() => SessionEntity, (session) => session.userId)
|
||||
sessions!: SessionEntity[]
|
||||
|
||||
@OneToMany(() => AccountEntity, (account) => account.userId)
|
||||
accounts!: AccountEntity[]
|
||||
}
|
||||
|
||||
@Entity({ name: "accounts" })
|
||||
export class AccountEntity {
|
||||
@PrimaryGeneratedColumn("uuid")
|
||||
id!: string
|
||||
|
||||
@Column({ type: "uuid" })
|
||||
userId!: string
|
||||
|
||||
@Column()
|
||||
type!: string
|
||||
|
||||
@Column()
|
||||
provider!: string
|
||||
|
||||
@Column()
|
||||
providerAccountId!: string
|
||||
|
||||
@Column({ type: "varchar", nullable: true })
|
||||
refresh_token!: string | null
|
||||
|
||||
@Column({ type: "varchar", nullable: true })
|
||||
access_token!: string | null
|
||||
|
||||
@Column({
|
||||
nullable: true,
|
||||
type: "bigint",
|
||||
transformer: transformer.bigint,
|
||||
})
|
||||
expires_at!: number | null
|
||||
|
||||
@Column({ type: "varchar", nullable: true })
|
||||
token_type!: string | null
|
||||
|
||||
@Column({ type: "varchar", nullable: true })
|
||||
scope!: string | null
|
||||
|
||||
@Column({ type: "varchar", nullable: true })
|
||||
id_token!: string | null
|
||||
|
||||
@Column({ type: "varchar", nullable: true })
|
||||
session_state!: string | null
|
||||
|
||||
@Column({ type: "varchar", nullable: true })
|
||||
oauth_token_secret!: string | null
|
||||
|
||||
@Column({ type: "varchar", nullable: true })
|
||||
oauth_token!: string | null
|
||||
|
||||
@ManyToOne(() => UserEntity, (user) => user.accounts, {
|
||||
createForeignKeyConstraints: true,
|
||||
})
|
||||
user!: UserEntity
|
||||
}
|
||||
|
||||
@Entity({ name: "sessions" })
|
||||
export class SessionEntity {
|
||||
@PrimaryGeneratedColumn("uuid")
|
||||
id!: string
|
||||
|
||||
@Column({ unique: true })
|
||||
sessionToken!: string
|
||||
|
||||
@Column({ type: "uuid" })
|
||||
userId!: string
|
||||
|
||||
@Column({ transformer: transformer.date })
|
||||
expires!: string
|
||||
|
||||
@ManyToOne(() => UserEntity, (user) => user.sessions)
|
||||
user!: UserEntity
|
||||
}
|
||||
|
||||
@Entity({ name: "verification_tokens" })
|
||||
export class VerificationTokenEntity {
|
||||
@PrimaryGeneratedColumn("uuid")
|
||||
id!: string
|
||||
|
||||
@Column()
|
||||
token!: string
|
||||
|
||||
@Column()
|
||||
identifier!: string
|
||||
|
||||
@Column({ transformer: transformer.date })
|
||||
expires!: string
|
||||
}
|
||||
```
|
||||
|
||||
2. Pass them to `TypeORMLegacyAdapter`
|
||||
|
||||
```javascript title="pages/api/auth/[...nextauth].js"
|
||||
import NextAuth from "next-auth"
|
||||
import { TypeORMLegacyAdapter } from "@next-auth/typeorm-legacy-adapter"
|
||||
import * as entities from "lib/entities"
|
||||
|
||||
export default NextAuth({
|
||||
adapter: TypeORMLegacyAdapter("yourconnectionstring", { entities }),
|
||||
...
|
||||
})
|
||||
```
|
||||
|
||||
:::tip Synchronize your database ♻
|
||||
The `synchronize: true` option in TypeORM will generate SQL that exactly matches the entities. This will automatically apply any changes it finds in the entity model. This is a useful option in development.
|
||||
:::
|
||||
|
||||
:::warning Using synchronize in production
|
||||
`synchronize: true` should not be enabled against production databases as it may cause data loss if the configured schema does not match the expected schema! We recommend that you synchronize/migrate your production database at build-time.
|
||||
:::
|
||||
|
||||
## Naming Conventions
|
||||
|
||||
If mixed snake_case and camelCase column names are an issue for you and/or your underlying database system, we recommend using TypeORM's naming strategy feature to change the target field names. There is a package called `typeorm-naming-strategies` which includes a `snake_case` strategy which will translate the fields from how NextAuth.js expects them, to snake_case in the actual database.
|
||||
|
||||
For example, you can add the naming convention option to the connection object in your NextAuth config.
|
||||
|
||||
```javascript title="pages/api/auth/[...nextauth].js"
|
||||
import NextAuth from "next-auth"
|
||||
import { TypeORMLegacyAdapter } from "@next-auth/typeorm-legacy-adapter"
|
||||
import { SnakeNamingStrategy } from 'typeorm-naming-strategies'
|
||||
|
||||
export default NextAuth({
|
||||
adapter: TypeORMLegacyAdapter({
|
||||
type: "mysql",
|
||||
host: "localhost",
|
||||
port: 3306,
|
||||
username: "test",
|
||||
password: "test",
|
||||
database: "test",
|
||||
namingStrategy: new SnakeNamingStrategy()
|
||||
}),
|
||||
...
|
||||
})
|
||||
```
|
||||
@@ -56,19 +56,13 @@ module.exports = {
|
||||
collapsed: true,
|
||||
items: [
|
||||
"adapters/models",
|
||||
"adapters/prisma",
|
||||
"adapters/fauna",
|
||||
"adapters/dynamodb",
|
||||
"adapters/firebase",
|
||||
"adapters/pouchdb",
|
||||
"adapters/mongodb",
|
||||
"adapters/mikro-orm",
|
||||
"adapters/neo4j",
|
||||
"adapters/typeorm",
|
||||
"adapters/pouchdb",
|
||||
"adapters/sequelize",
|
||||
"adapters/supabase",
|
||||
"adapters/mikro-orm",
|
||||
"adapters/dgraph",
|
||||
"adapters/upstash-redis",
|
||||
"adapters/xata",
|
||||
],
|
||||
},
|
||||
"warnings",
|
||||
|
||||
Reference in New Issue
Block a user