Compare commits

...

37 Commits

Author SHA1 Message Date
Thang Vu
3d8350c676 add timeout for test step 2022-12-20 11:45:56 +07:00
Balázs Orbán
6fdcaf6ebd update lock file 2022-12-19 04:35:15 +01:00
Balázs Orbán
d2f0ac446b Merge branch 'main' into chore/clean-dev-deps 2022-12-19 04:34:23 +01:00
Thang Vu
2c5244e67e feat: Enable turbo remote caching for GH Actions 2022-12-19 10:27:13 +07:00
Balázs Orbán
f7275c7527 chore: type updates
fix import

chore: more docs update
2022-12-19 04:03:03 +01:00
Balázs Orbán
e699ff14b8 docs: /reference sidebar improvements (#6115)
* wip

* 🤖 lazy commit

* 🤖 lazy commit

* revert some changes, remove prettier jsdoc plugin for now

* sidebar tweaks

* add adapter module docs

* remove provider docs

* embed all reflections under modules

Based on: https://github.com/TypeStrong/typedoc/issues/2006

Related: https://github.com/tgreyuk/typedoc-plugin-markdown/issues/338

* no trailing slash, update theme

* updates

* update snapshot

* update sidebar and overview
2022-12-19 01:00:06 +00:00
ndom91
6eab7ac25f chore(actions): revert var dump 2022-12-19 01:31:11 +01:00
ndom91
9b05dbc540 chore(actions): add path 2022-12-19 01:28:33 +01:00
ndom91
132a76d951 chore(actions): test github context 2022-12-19 01:26:54 +01:00
ndom91
66cbb522d9 Merge branch 'main' of ssh://github.com/nextauthjs/next-auth 2022-12-19 01:12:47 +01:00
ndom91
553924d902 chore(actions): fix validator path 2022-12-19 01:12:38 +01:00
Balázs Orbán
cba81f0b8c chore: add snippets 2022-12-18 14:12:56 +01:00
Balázs Orbán
b7171ab790 chore: tweak jsdoc formatting/linting 2022-12-18 14:06:00 +01:00
ndom91
43c8f663c6 Revert "fix: pnpm-lock.yaml"
This reverts commit b16b048991.
2022-12-18 04:06:37 +01:00
ndom91
b16b048991 fix: pnpm-lock.yaml 2022-12-18 04:05:16 +01:00
ndom91
62a5d70f9b Merge branch 'main' of ssh://github.com/nextauthjs/next-auth 2022-12-18 04:04:46 +01:00
Balázs Orbán
1b671ae83d docs: format landing page 2022-12-18 02:19:07 +00:00
Andrew Manzanero
cc4b9fc2fc fix(core): check for oidc account types in callback-handler.ts (#6108)
* check oidc account types

* Apply suggestions from code review

Co-authored-by: Balázs Orbán <info@balazsorban.com>
2022-12-18 01:46:33 +00:00
Nico Domino
4935166372 chore(docs): add provider-issue and github-discussions redirects (#6110) 2022-12-18 01:44:37 +00:00
Balázs Orbán
695f937dbd chore: change sync action comment 2022-12-18 01:18:08 +00:00
Balázs Orbán
c527801875 remove empty test, move configs 2022-12-18 01:42:17 +01:00
Balázs Orbán
20ba5e1fcd run formatter, include docs 2022-12-18 01:10:53 +01:00
Balázs Orbán
01d88733c3 don't format next-auth 2022-12-18 01:07:18 +01:00
Balázs Orbán
f0720cbbd8 move eslint and prettier configs to top 2022-12-18 01:05:31 +01:00
ndom91
ad9eec3676 chore(docs): add provider-issue and github-discussions redirects 2022-12-18 00:07:41 +01:00
Balázs Orbán
a264638274 migrate turbo config 2022-12-18 00:00:26 +01:00
Balázs Orbán
663c5ef23b chore: upgrade workspace dependencies 2022-12-18 00:00:18 +01:00
Balázs Orbán
2e924edcdf chore: stop sync next-auth-example from main branch 2022-12-17 19:40:20 +00:00
Balázs Orbán
c7627778eb chore: no prettier check yet 2022-12-17 14:33:52 +01:00
Balázs Orbán
8b5644453b docs: set up API reference generation 2022-12-17 14:26:14 +01:00
Balázs Orbán
84291d3e81 chore: fix formatting and linting 2022-12-16 15:57:55 +01:00
Nico Domino
67e5c236f6 chore(docs): wildcard path matching (#6092) 2022-12-16 14:22:51 +01:00
Nico Domino
8972defa4b chore(vercel): add errors and warnings subdomain redirects (#6091) 2022-12-16 14:10:39 +01:00
Aleš Vaupotič
85667dd681 docs(sveltekit): add note about deploying to providers other than vercel (#6075)
* Directions to deploy outside Vercel

An additional ENV variable is needed when deploying with another service.

* Updated as suggested, AUTH_TRUST_HOST is a boolean

Add AUTH_TRUST_HOST for deploy outside Vercel
2022-12-16 05:06:26 +01:00
Lluis Agusti
d9532745eb docs: update names to Auth.js (#6077) 2022-12-16 05:03:31 +01:00
Robert Soriano
1e6daa8304 chore(examples): use @auth/core in Nuxt playground (#6081)
* nuxt: rewrite server handler to use @auth/core

* nuxt: fix main tsconfig

* nuxt: remove unused module

* nuxt: update client and server ports

* nuxt: remove iframe style

* nuxt: update readme
2022-12-16 02:47:44 +00:00
meesvandongen
70a3e3f662 chore(docs): Fix nextjs.md code block (#6037)
chore: fix quotes
2022-12-16 01:00:22 +01:00
156 changed files with 4648 additions and 10367 deletions

12
.eslintignore Normal file
View File

@@ -0,0 +1,12 @@
../core/adapters.*
../core/index.*
../core/jwt
../core/lib
../core/providers
.gitignore
../frameworks-sveltekit/*.cjs
../frameworks-sveltekit/client.*
../frameworks-sveltekit/index.*
../frameworks-sveltekit/tests
../frameworks-sveltekit/.svelte-kit

View File

@@ -1,20 +1,23 @@
// @ts-check
const path = require("path")
/** @type {import("eslint").ESLint.ConfigData} */
module.exports = {
root: true,
parser: "@typescript-eslint/parser",
extends: ["standard-with-typescript", "prettier"],
rules: {
camelcase: "off",
"@typescript-eslint/naming-convention": "off",
"@typescript-eslint/strict-boolean-expressions": "off",
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/restrict-template-expressions": "off",
"@typescript-eslint/triple-slash-reference": "off",
"@typescript-eslint/promise-function-async": "off",
},
overrides: [
{
files: ["*.ts", "*.tsx"],
extends: ["standard-with-typescript", "prettier"],
rules: {
camelcase: "off",
"@typescript-eslint/naming-convention": "off",
"@typescript-eslint/strict-boolean-expressions": "off",
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/restrict-template-expressions": "off",
},
parserOptions: {
project: [
path.resolve(__dirname, "./packages/**/tsconfig.eslint.json"),
@@ -23,19 +26,57 @@ module.exports = {
],
},
},
{
files: ["*.test.ts", "*.test.js"],
env: { jest: true },
},
{
files: ["docs"],
plugins: ["@docusaurus"],
extends: ["plugin:@docusaurus/recommended"],
},
{
files: ["packages/core/src/**/*"],
plugins: ["jsdoc"],
extends: ["plugin:jsdoc/recommended"],
rules: {
"jsdoc/require-param": "off",
"jsdoc/require-returns": "off",
"jsdoc/require-jsdoc": [
"warn",
{ publicOnly: true, enableFixer: false },
],
"jsdoc/no-multi-asterisks": ["warn", { allowWhitespace: true }],
"jsdoc/tag-lines": "off",
},
},
{
files: ["packages/core/src/adapters.ts"],
rules: {
"@typescript-eslint/method-signature-style": "off",
},
},
{
files: ["packages/frameworks-sveltekit/**/*"],
plugins: ["svelte3", "@typescript-eslint"],
parserOptions: {
sourceType: "module",
ecmaVersion: 2020,
},
env: {
browser: true,
es2017: true,
node: true,
},
},
],
extends: ["prettier"],
globals: {
localStorage: "readonly",
location: "readonly",
fetch: "readonly",
},
rules: {
camelcase: "off",
},
plugins: ["jest"],
env: {
"jest/globals": true,
},
ignorePatterns: [".eslintrc.js"],
ignorePatterns: [
"**/dist/**",
"**/node_modules/**",
".eslintrc.js",
"**/.turbo/**",
"**/coverage/**",
"**/build/**",
],
}

7
.github/sync.yml vendored
View File

@@ -1,9 +1,4 @@
nextauthjs/next-auth-example:
- source: apps/example-nextjs
dest: .
deleteOrphaned: true
- .github/FUNDING.yml
- LICENSE
# Note that nextauthjs/next-auth-example syncs from the v4 branch
nextauthjs/sveltekit-auth-example:
- source: apps/example-sveltekit

View File

@@ -11,7 +11,7 @@ jobs:
- uses: actions/setup-node@v3
with:
node-version: 18
- name: 'Run issue validator'
run: node ./.github/actions/issue-validator/index.mjs
- name: "Run issue validator"
run: node /home/runner/work/next-auth/next-auth/.github/actions/issue-validator/index.mjs
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -33,9 +33,12 @@ jobs:
run: pnpm build
- name: Run tests
run: pnpm test
timeout-minutes: 15
env:
UPSTASH_REDIS_URL: ${{ secrets.UPSTASH_REDIS_URL }}
UPSTASH_REDIS_KEY: ${{ secrets.UPSTASH_REDIS_KEY }}
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
# - name: Coverage
# uses: codecov/codecov-action@v1
# with:

4
.gitignore vendored
View File

@@ -51,7 +51,7 @@ apps/dev/typeorm
/.vs/slnx.sqlite-journal
/.vs/slnx.sqlite
/.vs
.vscode
.vscode/generated*
# Jetbrains
.idea
@@ -86,6 +86,8 @@ packages/core/index.*
packages/core/jwt
packages/core/lib
packages/core/providers
packages/core/docs
docs/docs/reference/03-core
# SvelteKit

25
.prettierignore Normal file
View File

@@ -0,0 +1,25 @@
.DS_Store
node_modules
.turbo
# apps/example-* should have their standalonw config
# as they might be cloned via a template like https://github.com/nextauthjs/next-auth-example
# Note: The root is inside the package
# packages
dist
# docs
.docusaurus
build
static
# @auth/core
**/lib/styles/index.ts
**/providers/oauth-types.ts
# @auth/sveltekit
package
index.*
client.*
.svelte-kit

15
.prettierrc.js Normal file
View File

@@ -0,0 +1,15 @@
// @ts-check
/** @type {import("prettier").Config} */
module.exports = {
semi: false,
singleQuote: false,
overrides: [
{
files: "apps/dev/pages/api/auth/[...nextauth].ts",
options: {
printWidth: 150,
},
},
],
}

8
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,8 @@
{
"files.exclude": {
"packages/core/{jwt,lib,providers,*.js,*.d.ts*}": true,
"packages/next-auth/{client,core,css,jwt,next,providers,react,utils,*.js,*.d.ts}": true
},
"typescript.tsdk": "node_modules/typescript/lib",
"openInGitHub.remote.branch": "main",
}

18
.vscode/snippets.code-snippets vendored Normal file
View File

@@ -0,0 +1,18 @@
{
"oauth2-spec": {
"description": "Markdown link to OAuth 2 specification",
"scope": "typescript",
"prefix": "oauth2",
"body": [
"[OAuth 2](https://datatracker.ietf.org/doc/html/rfc6749)"
]
},
"oidc-spec": {
"description": "Markdown link to OpenID Connect specification",
"scope": "typescript",
"prefix": "oidc",
"body": [
"[OIDC](https://openid.net/specs/openid-connect-core-1_0.html)"
]
},
}

4
apps/dev/.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,4 @@
{
"typescript.tsdk": "../../node_modules/.pnpm/typescript@4.8.4/node_modules/typescript/lib",
"typescript.enablePromptUseWorkspaceTsdk": true
}

View File

@@ -6,7 +6,6 @@
"scripts": {
"clean": "rm -rf .next",
"dev": "next dev",
"lint": "next lint",
"build": "next build",
"start": "next start",
"email": "fake-smtp-server",

View File

@@ -1,12 +0,0 @@
root = true
[*]
indent_size = 2
indent_style = space
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false

View File

@@ -1,4 +0,0 @@
dist
node_modules
tsconfig.json
package.json

View File

@@ -1,10 +0,0 @@
{
"extends": [
"@nuxtjs/eslint-config-typescript"
],
"rules": {
"@typescript-eslint/no-unused-vars": [
"off"
]
}
}

View File

@@ -0,0 +1,7 @@
module.exports = {
root: true,
extends: ['@nuxt/eslint-config'],
rules: {
'vue/multi-word-component-names': 'off'
}
}

View File

@@ -1,52 +1,4 @@
# Dependencies
node_modules
# Logs
*.log*
# Temp directories
.temp
.tmp
.cache
# Yarn
**/.yarn/cache
**/.yarn/*state*
# Generated dirs
dist
# Nuxt
.nuxt
.output
.vercel_build_output
.build-*
.env
.netlify
# Env
.env
# Testing
reports
coverage
*.lcov
.nyc_output
# VSCode
.vscode
# Intellij idea
*.iml
.idea
# OSX
.DS_Store
.AppleDouble
.LSOverride
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
.vercel
dist
output

View File

@@ -1 +0,0 @@
imports.autoImport=false

View File

@@ -1,21 +1,13 @@
# NextAuth + Nuxt 3 Playground
> The example repository is maintained from a [monorepo](https://github.com/nextauthjs/next-auth/tree/main/apps/playground-nuxt). Pull Requests should be opened against [`nextauthjs/next-auth`](https://github.com/nextauthjs/next-auth).
NextAuth.js is committed to bringing easy authentication to other frameworks. [#2294](https://github.com/nextauthjs/next-auth/issues/2294)
Nuxt 3 support with NextAuth.js is currently experimental. This directory contains a minimal, proof-of-concept application. Parts of this is expected to be abstracted away into a package like` @next-auth/nuxt.`
This package uses Nuxt's [module starter](https://github.com/nuxt/starter/tree/module).
Demo: https://next-auth-nuxt-demo.vercel.app
Nuxt 3 support with Auth.js is currently experimental. This directory contains a minimal, proof-of-concept application. Parts of this is expected to be abstracted away into a package like `@auth/nuxt`.
## Getting Started
### Add the module to the modules section of `nuxt.config.ts`:
1. Setup your environment variables in `nuxt.config.ts`:
```ts
export default defineNuxtConfig({
// temporary module name.
modules: ['next-auth-nuxt'],
// https://v3.nuxtjs.org/migration/runtime-config#runtime-config
runtimeConfig: {
secret: process.env.NEXTAUTH_SECRET
@@ -23,86 +15,36 @@ export default defineNuxtConfig({
clientId: process.env.GITHUB_CLIENT_ID,
clientSecret: process.env.GITHUB_CLIENT_SECRET
}
},
// https://v3.nuxtjs.org/guide/concepts/esm#aliasing-libraries
// Fix for GithubProvider (or whichever provider you choose) is not a function error in Vite
alias: {
'next-auth/providers/github': 'node_modules/next-auth/providers/github.js'
}
})
```
### Add API route
2. Set up Auth.js options
To add `NextAuth.js` to a project create a file called `[...].ts` in `server/api/auth`. This contains the dynamic route handler for NextAuth.js which will also contain all of your global NextAuth.js configurations.
Go to the API handler file (`server/api/auth/[...].ts`) and setup your providers. This file contains the dynamic route handler for Auth.js which will also contain all of your global Auth.js configurations.
Here's an example of what it looks like:
```ts
// ~/server/api/auth/[...].ts
import { NextAuthNuxtHandler } from 'next-auth-nuxt/handler'
import GithubProvider from 'next-auth/providers/github'
// server/api/auth/[...].ts
import { NuxtAuthHandler } from '@/lib/auth/server'
import GithubProvider from '@auth/core/providers/github'
import type { AuthOptions } from '@auth/core'
const runtimeConfig = useRuntimeConfig()
export const authOptions = {
export const authOptions: AuthOptions = {
secret: runtimeConfig.secret,
providers: [
GithubProvider({
clientId: runtimeConfig.github.clientId,
clientSecret: runtimeConfig.github.clientSecret
}),
],
})
]
}
export default NextAuthNuxtHandler(authOptions)
export default NuxtAuthHandler(authOptions)
```
All requests to `/api/auth/*` (`signIn`, `callback`, `signOut`, etc.) will automatically be handled by NextAuth.js.
### Frontend - Add Vue Composable
The `useSession()` Vue Composable is the easiest way to check if someone is signed in.
```html
<script setup lang="ts">
const { data: session } = useSession()
</script>
<template>
<div v-if="session">
Signed in as {{ session.user.email }} <br />
<button @click="signOut">Sign out</button>
</div>
<div v-else>
Not signed in <br />
<button @click="signIn">Sign in</button>
</div>
</template>
```
### Backend - API Route
To protect an API Route, you can use the `getServerSession()` method.
```ts
import { getServerSession } from 'next-auth-nuxt/handler'
import { authOptions } from '~/server/api/auth/[...]'
export default defineEventHandler(async (event) => {
const session = await getServerSession(event, authOptions)
if (session) {
return {
content: 'This is protected content. You can access this content because you are signed in.'
}
}
return {
error: 'You must be signed in to view the protected content on this page.'
}
})
```
## Development
- Run `pnpm dev:generate` to generate type stubs.
- Use `pnpm dev` to start `playground` in development mode.
All requests to `/api/auth/*` (`signIn`, `callback`, `signOut`, etc.) will automatically be handled by Auth.js.

View File

@@ -0,0 +1,30 @@
<template>
<div>
<Header />
<NuxtPage />
</div>
</template>
<style>
body {
font-family: -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell, Noto Sans, sans-serif, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
padding: 0 1rem 1rem 1rem;
max-width: 680px;
margin: 0 auto;
background: #fff;
color: #333;
}
li,
p {
line-height: 1.5rem;
}
a {
font-weight: 500;
}
hr {
border: 1px solid #ddd;
}
</style>

View File

@@ -1 +0,0 @@
export * from './dist/runtime/client'

View File

@@ -0,0 +1,139 @@
<script setup lang="ts">
import { signIn, signOut } from '@/lib/auth/client'
const session = useSession()
</script>
<template>
<header>
<div class="signedInStatus">
<p :class="['nojs-show', 'loaded']">
<template v-if="session">
<span v-if="session.user?.image" :style="{ backgroundImage: `url(${session.user.image})` }" class="avatar" />
<span class="signedInText">
<small>Signed in as</small><br>
<strong>{{ session.user?.email || session.user?.name }}</strong>
</span>
<a href="/api/auth/signout" class="button" @click.prevent="signOut">Sign out</a>
</template>
<template v-else>
<span class="notSignedInText">You are not signed in</span>
<a href="/api/auth/signin" class="buttonPrimary" @click.prevent="signIn">Sign in</a>
</template>
</p>
</div>
<nav>
<ul class="navItems">
<li class="navItem">
<NuxtLink to="/">
Home
</NuxtLink>
</li>
<li class="navItem">
<NuxtLink to="/protected">
Protected
</NuxtLink>
</li>
</ul>
</nav>
</header>
</template>
<style>
.nojs-show {
opacity: 1;
top: 0;
}
.signedInStatus {
display: block;
min-height: 4rem;
width: 100%;
}
.loading,
.loaded {
position: relative;
top: 0;
opacity: 1;
overflow: hidden;
border-radius: 0 0 .6rem .6rem;
padding: .6rem 1rem;
margin: 0;
background-color: rgba(0,0,0,.05);
transition: all 0.2s ease-in;
}
.loading {
top: -2rem;
opacity: 0;
}
.signedInText,
.notSignedInText {
position: absolute;
padding-top: .8rem;
left: 1rem;
right: 6.5rem;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
display: inherit;
z-index: 1;
line-height: 1.3rem;
}
.signedInText {
padding-top: 0rem;
left: 4.6rem;
}
.avatar {
border-radius: 2rem;
float: left;
height: 2.8rem;
width: 2.8rem;
background-color: white;
background-size: cover;
background-repeat: no-repeat;
}
.button,
.buttonPrimary {
float: right;
margin-right: -.4rem;
font-weight: 500;
border-radius: .3rem;
cursor: pointer;
font-size: 1rem;
line-height: 1.4rem;
padding: .7rem .8rem;
position: relative;
z-index: 10;
background-color: transparent;
color: #555;
}
.buttonPrimary {
background-color: #346df1;
border-color: #346df1;
color: #fff;
text-decoration: none;
padding: .7rem 1.4rem;
}
.buttonPrimary:hover {
box-shadow: inset 0 0 5rem rgba(0,0,0,0.2)
}
.navItems {
margin-bottom: 2rem;
padding: 0;
list-style: none;
}
.navItem {
display: inline-block;
margin-right: 1rem;
}
</style>

View File

@@ -0,0 +1,5 @@
import { Session } from '@auth/core'
export default function useSession() {
return useState<Session | null>('session', () => null)
}

View File

@@ -1 +0,0 @@
export * from './dist/runtime/server/handler'

View File

@@ -0,0 +1,107 @@
import type {
LiteralUnion,
SignInOptions,
SignInAuthorizationParams,
SignOutParams,
} from './types'
import type {
BuiltInProviderType,
RedirectableProviderType,
} from '@auth/core/providers'
/**
* Client-side method to initiate a signin flow
* or send the user to the signin page listing all possible providers.
* Automatically adds the CSRF token to the request.
*
* [Documentation](https://next-auth.js.org/getting-started/client#signin)
*/
export async function signIn<
P extends RedirectableProviderType | undefined = undefined
>(
providerId?: LiteralUnion<
P extends RedirectableProviderType
? P | BuiltInProviderType
: BuiltInProviderType
>,
options?: SignInOptions,
authorizationParams?: SignInAuthorizationParams
) {
const { callbackUrl = window.location.href, redirect = true } = options ?? {}
// TODO: Support custom providers
const isCredentials = providerId === "credentials"
const isEmail = providerId === "email"
const isSupportingReturn = isCredentials || isEmail
// TODO: Handle custom base path
const signInUrl = `/api/auth/${
isCredentials ? "callback" : "signin"
}/${providerId}`
const _signInUrl = `${signInUrl}?${new URLSearchParams(authorizationParams)}`
// TODO: Handle custom base path
// TODO: Remove this since Sveltekit offers the CSRF protection via origin check
const { csrfToken } = await $fetch("/api/auth/csrf")
console.log(_signInUrl)
const res = await fetch(_signInUrl, {
method: "post",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"X-Auth-Return-Redirect": "1",
},
// @ts-expect-error -- ignore
body: new URLSearchParams({
...options,
csrfToken,
callbackUrl,
}),
})
const data = await res.clone().json()
const error = new URL(data.url).searchParams.get("error")
if (redirect || !isSupportingReturn || !error) {
// TODO: Do not redirect for Credentials and Email providers by default in next major
window.location.href = data.url ?? callbackUrl
// If url contains a hash, the browser does not reload the page. We reload manually
if (data.url.includes("#")) window.location.reload()
return
}
return res
}
/**
* Signs the user out, by removing the session cookie.
* Automatically adds the CSRF token to the request.
*
* [Documentation](https://next-auth.js.org/getting-started/client#signout)
*/
export async function signOut(options?: SignOutParams) {
const { callbackUrl = window.location.href } = options ?? {}
// TODO: Custom base path
// TODO: Remove this since Sveltekit offers the CSRF protection via origin check
const csrfTokenResponse = await fetch("/api/auth/csrf")
const { csrfToken } = await csrfTokenResponse.json()
const res = await fetch(`/api/auth/signout`, {
method: "post",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"X-Auth-Return-Redirect": "1",
},
body: new URLSearchParams({
csrfToken,
callbackUrl,
}),
})
const data = await res.json()
const url = data.url ?? callbackUrl
window.location.href = url
// If url contains a hash, the browser does not reload the page. We reload manually
if (url.includes("#")) window.location.reload()
}

View File

@@ -0,0 +1,45 @@
import { AuthHandler, AuthOptions, Session } from '@auth/core'
import { fromNodeMiddleware, H3Event } from 'h3'
import getURL from 'requrl'
import { createMiddleware } from "@hattip/adapter-node";
export function NuxtAuthHandler (options: AuthOptions) {
async function handler(ctx: { request: Request }) {
options.trustHost ??= true
return AuthHandler(ctx.request, options)
}
const middleware = createMiddleware(handler)
return fromNodeMiddleware(middleware)
}
export async function getSession(
event: H3Event,
options: AuthOptions
): Promise<Session | null> {
options.trustHost ??= true
const headers = getRequestHeaders(event)
const nodeHeaders = new Headers()
const url = new URL('/api/auth/session', getURL(event.node.req))
Object.keys(headers).forEach((key) => {
nodeHeaders.append(key, headers[key] as any)
})
const response = await AuthHandler(
new Request(url, { headers: nodeHeaders }),
options
)
const { status = 200 } = response
const data = await response.json()
if (!data || !Object.keys(data).length) return null
if (status === 200) return data
throw new Error(data.message)
}

View File

@@ -0,0 +1,42 @@
// Taken from next-auth/react
import type { BuiltInProviderType, ProviderType } from '@auth/core/providers'
/**
* Util type that matches some strings literally, but allows any other string as well.
* @source https://github.com/microsoft/TypeScript/issues/29729#issuecomment-832522611
*/
export declare type LiteralUnion<T extends U, U = string> = T | (U & Record<never, never>);
export interface ClientSafeProvider {
id: LiteralUnion<BuiltInProviderType>;
name: string;
type: ProviderType;
signinUrl: string;
callbackUrl: string;
}
export interface SignInOptions extends Record<string, unknown> {
/**
* Specify to which URL the user will be redirected after signing in. Defaults to the page URL the sign-in is initiated from.
*
* [Documentation](https://next-auth.js.org/getting-started/client#specifying-a-callbackurl)
*/
callbackUrl?: string;
/** [Documentation](https://next-auth.js.org/getting-started/client#using-the-redirect-false-option) */
redirect?: boolean;
}
export interface SignInResponse {
error: string | undefined;
status: number;
ok: boolean;
url: string | null;
}
/** Match `inputType` of `new URLSearchParams(inputType)` */
export declare type SignInAuthorizationParams = string | string[][] | Record<string, string> | URLSearchParams;
/** [Documentation](https://next-auth.js.org/getting-started/client#using-the-redirect-false-option-1) */
export interface SignOutResponse {
url: string;
}
export interface SignOutParams<R extends boolean = true> {
/** [Documentation](https://next-auth.js.org/getting-started/client#specifying-a-callbackurl-1) */
callbackUrl?: string;
/** [Documentation](https://next-auth.js.org/getting-started/client#using-the-redirect-false-option-1 */
redirect?: R;
}

View File

@@ -1,9 +1,4 @@
import MyModule from '../src/module'
export default defineNuxtConfig({
modules: [
MyModule
],
// https://v3.nuxtjs.org/migration/runtime-config#runtime-config
runtimeConfig: {
secret: process.env.NEXTAUTH_SECRET,
@@ -12,9 +7,11 @@ export default defineNuxtConfig({
clientSecret: process.env.GITHUB_CLIENT_SECRET
}
},
// https://v3.nuxtjs.org/guide/concepts/esm#aliasing-libraries
// Fix for GithubProvider is not a function error in Vite
alias: {
'next-auth/providers/github': 'node_modules/next-auth/providers/github.js'
vite: {
define: {
'process.env.NEXTAUTH_URL': JSON.stringify(process.env.NEXTAUTH_URL),
'process.env.AUTH_TRUST_HOST': JSON.stringify(process.env.AUTH_TRUST_HOST),
'process.env.VERCEL_URL': JSON.stringify(process.env.VERCEL_URL),
}
}
})

View File

@@ -1,49 +1,22 @@
{
"name": "next-auth-nuxt",
"type": "module",
"version": "0.0.0",
"packageManager": "pnpm@7.1.1",
"license": "MIT",
"main": "./dist/module.cjs",
"types": "./dist/types.d.ts",
"exports": {
".": {
"import": "./dist/module.mjs",
"require": "./dist/module.cjs"
},
"./handler": {
"import": "./dist/runtime/server/handler.mjs",
"types": "./dist/runtime/server/handler.d.ts"
},
"./client": {
"import": "./dist/runtime/client/index.mjs",
"types": "./dist/runtime/client/index.d.ts"
}
},
"files": [
"dist",
"handler.d.ts",
"client.d.ts"
],
"name": "playground-nuxt",
"private": true,
"scripts": {
"prepack": "nuxt-module-build",
"dev": "pnpm prepack && nuxi dev playground",
"dev:build": "nuxi build playground",
"dev:build:vercel": "NITRO_PRESET=vercel nuxi build playground",
"dev:prepare": "nuxt-module-build --stub && nuxi prepare playground"
},
"dependencies": {
"@nuxt/kit": "^3.0.0-rc.13",
"h3": "^0.8.6",
"next-auth": "^4.16.2",
"pathe": "^0.3.9"
"build": "nuxt build",
"dev": "export NODE_OPTIONS='--no-experimental-fetch' && nuxt dev",
"generate": "nuxt generate",
"preview": "nuxt preview",
"postinstall": "nuxt prepare"
},
"devDependencies": {
"@nuxt/module-builder": "^0.2.0",
"@nuxt/schema": "^3.0.0-rc.12",
"@nuxtjs/eslint-config-typescript": "^11.0.0",
"eslint": "^8.26.0",
"nuxt": "^3.0.0-rc.13",
"next-auth-nuxt": "workspace:*"
"@nuxt/eslint-config": "^0.1.1",
"eslint": "^8.29.0",
"h3": "1.0.2",
"nuxt": "3.0.0"
},
"dependencies": {
"@auth/core": "workspace:*",
"@hattip/adapter-node": "^0.0.22",
"requrl": "^3.0.2"
}
}

View File

@@ -0,0 +1,8 @@
<template>
<div>
<h1>Nuxt Auth Example</h1>
<p>
This is an example site to demonstrate how to use <a href="https://v3.nuxtjs.org/">Nuxt 3</a> with <a href="https://authjs.dev/">Auth.js</a> for authentication.
</p>
</div>
</template>

View File

@@ -0,0 +1,18 @@
<script setup lang="ts">
const session = useSession()
definePageMeta({
middleware: 'auth'
})
</script>
<template>
<div>
<h1>Protected Page</h1>
<p>
This is a protected content. You can access this content because you are
signed in.
</p>
<p>Session expiry: {{ session?.expires }}</p>
</div>
</template>

View File

@@ -1,40 +0,0 @@
<template>
<div>
<Header />
<NuxtPage />
<Footer />
</div>
</template>
<style>
body {
font-family: -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell, Noto Sans, sans-serif, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
padding: 0 1rem 1rem 1rem;
max-width: 680px;
margin: 0 auto;
background: #fff;
color: #333;
}
li,
p {
line-height: 1.5rem;
}
a {
font-weight: 500;
}
hr {
border: 1px solid #ddd;
}
iframe {
background: #ccc;
border: 1px solid #ccc;
height: 10rem;
width: 100%;
border-radius: .5rem;
filter: invert(1);
}
</style>

View File

@@ -1,8 +0,0 @@
<template>
<div>
<h1>Access Denied</h1>
<p>
<a href="/api/auth/signin">You must be signed in to view this page</a>
</p>
</div>
</template>

View File

@@ -1,30 +0,0 @@
<template>
<footer class="fotter">
<hr>
<ul class="navItems">
<li class="navItem">
<a href="https://github.com/nextauthjs/next-auth/tree/main/apps/playground-nuxt">Demo GitHub</a>
</li>
<li class="navItem">
<a href="https://next-auth.js.org">Next.js Documentation</a>
</li>
</ul>
</footer>
</template>
<style>
.footer {
margin-top: 2rem;
}
.navItems {
margin-bottom: 1rem;
padding: 0;
list-style: none;
}
.navItem {
display: inline-block;
margin-right: 1rem;
}
</style>

View File

@@ -1,155 +0,0 @@
<script setup lang="ts">
import { useSession, signIn, signOut, computed } from '#imports'
const { data: session, status } = useSession()
const loading = computed(() => status.value === 'loading')
</script>
<template>
<header>
<div class="signedInStatus">
<p :class="['nojs-show', !session && loading ? 'loading' : 'loaded']">
<template v-if="session">
<span v-if="session.user?.image" :style="{ backgroundImage: `url(${session.user.image})` }" class="avatar" />
<span class="signedInText">
<small>Signed in as</small><br>
<strong>{{ session.user?.email || session.user?.name }}</strong>
</span>
<a href="/api/auth/signout" class="button" @click.prevent="signOut">Sign out</a>
</template>
<template v-else>
<span class="notSignedInText">You are not signed in</span>
<a href="/api/auth/signin" class="buttonPrimary" @click.prevent="signIn">Sign in</a>
</template>
</p>
</div>
<nav>
<ul class="navItems">
<li class="navItem">
<NuxtLink to="/">
Home
</NuxtLink>
</li>
<li class="navItem">
<NuxtLink to="/client">
Client
</NuxtLink>
</li>
<li class="navItem">
<NuxtLink to="/server">
Server
</NuxtLink>
</li>
<li class="navItem">
<NuxtLink to="/protected">
Protected
</NuxtLink>
</li>
<li class="navItem">
<NuxtLink to="/api-example">
API
</NuxtLink>
</li>
</ul>
</nav>
</header>
</template>
<style>
.nojs-show {
opacity: 1;
top: 0;
}
.signedInStatus {
display: block;
min-height: 4rem;
width: 100%;
}
.loading,
.loaded {
position: relative;
top: 0;
opacity: 1;
overflow: hidden;
border-radius: 0 0 .6rem .6rem;
padding: .6rem 1rem;
margin: 0;
background-color: rgba(0,0,0,.05);
transition: all 0.2s ease-in;
}
.loading {
top: -2rem;
opacity: 0;
}
.signedInText,
.notSignedInText {
position: absolute;
padding-top: .8rem;
left: 1rem;
right: 6.5rem;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
display: inherit;
z-index: 1;
line-height: 1.3rem;
}
.signedInText {
padding-top: 0rem;
left: 4.6rem;
}
.avatar {
border-radius: 2rem;
float: left;
height: 2.8rem;
width: 2.8rem;
background-color: white;
background-size: cover;
background-repeat: no-repeat;
}
.button,
.buttonPrimary {
float: right;
margin-right: -.4rem;
font-weight: 500;
border-radius: .3rem;
cursor: pointer;
font-size: 1rem;
line-height: 1.4rem;
padding: .7rem .8rem;
position: relative;
z-index: 10;
background-color: transparent;
color: #555;
}
.buttonPrimary {
background-color: #346df1;
border-color: #346df1;
color: #fff;
text-decoration: none;
padding: .7rem 1.4rem;
}
.buttonPrimary:hover {
box-shadow: inset 0 0 5rem rgba(0,0,0,0.2)
}
.navItems {
margin-bottom: 2rem;
padding: 0;
list-style: none;
}
.navItem {
display: inline-block;
margin-right: 1rem;
}
</style>

View File

@@ -1,4 +0,0 @@
{
"name": "playground",
"private": true
}

View File

@@ -1,15 +0,0 @@
<template>
<div>
<h1>API Example</h1>
<p>The examples below show responses from the example API endpoints.</p>
<p>
<em>You must be signed in to see responses.</em>
</p>
<h2>Session</h2>
<p>/api/examples/session</p>
<iframe src="/api/examples/session" />
<h2>JSON Web Token</h2>
<p>/api/examples/jwt</p>
<iframe src="/api/examples/jwt" />
</div>
</template>

View File

@@ -1,18 +0,0 @@
<template>
<div>
<h1>Client Side Rendering</h1>
<p>
This page uses the <strong>useSession()</strong> Vue Composable in the <strong>&lt;Header/&gt;</strong> component.
</p>
<p>
The <strong>useSession()</strong> Vue Composable is easy to use and allows pages to render very quickly.
</p>
<p>
The advantage of this approach is that session state is shared between pages by using a provided session via <strong>Vue Plugin</strong> so
that navigation between pages using <strong>useSession()</strong> is very fast.
</p>
<p>
The disadvantage of <strong>useSession()</strong> is that it requires client side JavaScript.
</p>
</div>
</template>

View File

@@ -1,8 +0,0 @@
<template>
<div>
<h1>Nuxt 3 + NextAuth.js Example</h1>
<p>
This is an example site to demonstrate how to use <a href="https://v3.nuxtjs.org/">Nuxt 3</a> with <a href="https://next-auth.js.org">NextAuth.js</a> for authentication.
</p>
</div>
</template>

View File

@@ -1,19 +0,0 @@
<script setup lang="ts">
import { useSession, useFetch, useLazyFetch } from '#imports'
import AccessDenied from '~/components/AccessDenied.vue'
const { data: session } = useSession()
const { data } = await useLazyFetch('/api/examples/protected', {
server: false
})
</script>
<template>
<div>
<AccessDenied v-if="!session" />
<template v-else>
<h1>Protected Page</h1>
<p><strong>{{ data?.content || "\u00a0" }}</strong></p>
</template>
</div>
</template>

View File

@@ -1,24 +0,0 @@
<script setup lang="ts">
import { useFetch } from '#imports'
await useFetch('/api/examples/session')
</script>
<template>
<div>
<h1>Server Side Rendering</h1>
<p>
This page uses the <strong>getServerSession()</strong> method inside an api route and is fetched using the <strong>useFetch()</strong> composable.
</p>
<p>
Using <strong>getServerSession()</strong> is the recommended approach if you need to
support Server Side Rendering with authentication.
</p>
<p>
The advantage of Server Side Rendering is this page does not require client side JavaScript.
</p>
<p>
The disadvantage of Server Side Rendering is that this page is slower to render.
</p>
</div>
</template>

View File

@@ -1,17 +0,0 @@
import { NextAuthNuxtHandler } from 'next-auth-nuxt/handler'
import GithubProvider from 'next-auth/providers/github'
import type { NextAuthOptions } from 'next-auth'
const runtimeConfig = useRuntimeConfig()
export const authOptions: NextAuthOptions = {
secret: runtimeConfig.secret,
providers: [
GithubProvider({
clientId: runtimeConfig.github.clientId,
clientSecret: runtimeConfig.github.clientSecret
})
]
}
export default NextAuthNuxtHandler(authOptions)

View File

@@ -1,10 +0,0 @@
import { getToken } from 'next-auth/jwt'
export default defineEventHandler(async (event) => {
// @ts-expect-error: cookies property is not present in h3
event.req.cookies = parseCookies(event)
const token = await getToken({
req: event.req
})
return token
})

View File

@@ -1,16 +0,0 @@
import { getServerSession } from 'next-auth-nuxt/handler'
import { authOptions } from '../auth/[...]'
export default defineEventHandler(async (event) => {
const session = await getServerSession(event, authOptions)
if (session) {
return {
content: 'This is protected content. You can access this content because you are signed in.'
}
}
return {
error: 'You must be signed in to view the protected content on this page.'
}
})

View File

@@ -1,7 +0,0 @@
import { getServerSession } from 'next-auth-nuxt/handler'
import { authOptions } from '../auth/[...]'
export default defineEventHandler(async (event) => {
const session = await getServerSession(event, authOptions)
return session
})

View File

@@ -0,0 +1,19 @@
import { Session } from '@auth/core'
export default defineNuxtPlugin(async () => {
const session = useSession()
addRouteMiddleware('auth', () => {
if (!session.value) return navigateTo('/')
})
if (process.server) {
const data = await $fetch<Session>('/api/auth/session', {
headers: useRequestHeaders() as any
})
const hasSession = data && Object.keys(data).length
session.value = hasSession ? data : null
}
})

File diff suppressed because it is too large Load Diff

View File

@@ -1,2 +0,0 @@
packages:
- playground

View File

@@ -0,0 +1,17 @@
import { NuxtAuthHandler } from '@/lib/auth/server'
import GithubProvider from '@auth/core/providers/github'
import type { AuthOptions } from '@auth/core'
const runtimeConfig = useRuntimeConfig()
export const authOptions: AuthOptions = {
secret: runtimeConfig.secret,
providers: [
GithubProvider({
clientId: runtimeConfig.github.clientId,
clientSecret: runtimeConfig.github.clientSecret
})
]
}
export default NuxtAuthHandler(authOptions)

View File

@@ -1,40 +0,0 @@
import { fileURLToPath } from 'url'
import { addImports, addPlugin, defineNuxtModule, extendViteConfig } from '@nuxt/kit'
import { resolve } from 'pathe'
export interface ModuleOptions {
}
export default defineNuxtModule<ModuleOptions>({
meta: {
name: 'next-auth-nuxt',
configKey: 'auth'
},
defaults: {
},
async setup (_options, nuxt) {
const runtimeDir = fileURLToPath(new URL('./runtime', import.meta.url))
nuxt.options.build.transpile.push(runtimeDir)
addPlugin(resolve(runtimeDir, 'plugin.client'))
// Composables are auto-imported in client.
const client = resolve(runtimeDir, 'client')
await addImports([
{ name: 'getSession', from: client },
{ name: 'getCsrfToken', from: client },
{ name: 'getProviders', from: client },
{ name: 'signIn', from: client },
{ name: 'signOut', from: client },
{ name: 'useSession', from: client }
])
// We can safely expose this to client.
extendViteConfig((config) => {
config.define = config.define || {}
config.define['process.env.NEXTAUTH_URL'] = JSON.stringify(process.env.NEXTAUTH_URL)
config.define['process.env.NEXTAUTH_URL_INTERNAL'] = JSON.stringify(process.env.NEXTAUTH_URL_INTERNAL)
config.define['process.env.VERCEL_URL'] = JSON.stringify(process.env.VERCEL_URL)
})
}
})

View File

@@ -1,369 +0,0 @@
import type { NextAuthClientConfig } from 'next-auth/client/_utils'
import type { Plugin, Ref } from 'vue'
import { ref, reactive, computed, inject, toRefs } from 'vue'
import { BroadcastChannel, apiBaseUrl, fetchData, now } from 'next-auth/client/_utils'
import type { Session } from 'next-auth'
import type {
BuiltInProviderType,
RedirectableProviderType
} from 'next-auth/providers'
import type { H3EventContext } from 'h3'
import parseUrl from '../lib/parse-url'
import _logger, { proxyLogger } from '../lib/logger'
import type {
ClientSafeProvider,
LiteralUnion,
SessionProviderProps,
SignInAuthorizationParams,
SignInOptions,
SignInResponse,
SignOutParams,
SignOutResponse
} from '../types'
// This behaviour mirrors the default behaviour for getting the site name that
// happens server side in server/index.js
// 1. An empty value is legitimate when the code is being invoked client side as
// relative URLs are valid in that context and so defaults to empty.
// 2. When invoked server side the value is picked up from an environment
// variable and defaults to 'http://localhost:3000'.
const __NEXTAUTH: NextAuthClientConfig = {
baseUrl: parseUrl(process.env.NEXTAUTH_URL ?? process.env.VERCEL_URL).origin,
basePath: parseUrl(process.env.NEXTAUTH_URL).path,
baseUrlServer: parseUrl(
process.env.NEXTAUTH_URL_INTERNAL ??
process.env.NEXTAUTH_URL ??
process.env.VERCEL_URL
).origin,
basePathServer: parseUrl(
process.env.NEXTAUTH_URL_INTERNAL ?? process.env.NEXTAUTH_URL
).path,
_lastSync: 0,
_session: undefined,
_getSession: () => {}
}
export interface CtxOrReq {
req?: H3EventContext['req']
event?: { req: H3EventContext['req'] }
}
export type GetSessionParams = CtxOrReq & {
event?: 'storage' | 'timer' | 'hidden' | string
triggerEvent?: boolean
broadcast?: boolean
}
const logger = proxyLogger(_logger, __NEXTAUTH.basePath)
const broadcast = BroadcastChannel()
function isServer () {
return (process as any).server
}
export async function getSession (params?: GetSessionParams) {
const session = await fetchData<Session>(
'session',
__NEXTAUTH,
logger,
params
)
if (params?.broadcast ?? true) { broadcast.post({ event: 'session', data: { trigger: 'getSession' } }) }
return session
}
/**
* Returns the current Cross Site Request Forgery Token (CSRF Token)
* required to make POST requests (e.g. for signing in and signing out).
* You likely only need to use this if you are not using the built-in
* `signIn()` and `signOut()` methods.
*
* [Documentation](https://next-auth.js.org/getting-started/client#getcsrftoken)
*/
export async function getCsrfToken (params?: CtxOrReq) {
const response = await fetchData<{ csrfToken: string }>(
'csrf',
__NEXTAUTH,
logger,
params
)
return response?.csrfToken
}
/**
* It calls `/api/auth/providers` and returns
* a list of the currently configured authentication providers.
* It can be useful if you are creating a dynamic custom sign in page.
*
* [Documentation](https://next-auth.js.org/getting-started/client#getproviders)
*/
export async function getProviders () {
return await fetchData<
Record<LiteralUnion<BuiltInProviderType>, ClientSafeProvider>
>('providers', __NEXTAUTH, logger)
}
/**
* Client-side method to initiate a signin flow
* or send the user to the signin page listing all possible providers.
* Automatically adds the CSRF token to the request.
*
* [Documentation](https://next-auth.js.org/getting-started/client#signin)
*/
export async function signIn<
P extends RedirectableProviderType | undefined = undefined,
> (
provider?: LiteralUnion<BuiltInProviderType>,
options?: SignInOptions,
authorizationParams?: SignInAuthorizationParams
): Promise<
P extends RedirectableProviderType ? SignInResponse | undefined : undefined
> {
const { callbackUrl = window.location.href, redirect = true } = options ?? {}
const baseUrl = apiBaseUrl(__NEXTAUTH)
const providers = await getProviders()
if (!providers) {
window.location.href = `${baseUrl}/error`
return
}
if (!provider || !(provider in providers)) {
window.location.href = `${baseUrl}/signin?${new URLSearchParams({
callbackUrl
})}`
return
}
const isCredentials = providers[provider].type === 'credentials'
const isEmail = providers[provider].type === 'email'
const isSupportingReturn = isCredentials || isEmail
const signInUrl = `${baseUrl}/${
isCredentials ? 'callback' : 'signin'
}/${provider}`
const _signInUrl = `${signInUrl}?${new URLSearchParams(authorizationParams)}`
const res = await fetch(_signInUrl, {
method: 'post',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
// @ts-expect-error: Internal
body: new URLSearchParams({
...options,
csrfToken: await getCsrfToken(),
callbackUrl,
json: true
})
})
const data = await res.json()
if (redirect || !isSupportingReturn) {
const url = data.url ?? callbackUrl
window.location.href = url
// If url contains a hash, the browser does not reload the page. We reload manually
if (url.includes('#')) { window.location.reload() }
return
}
const error = new URL(data.url).searchParams.get('error')
if (res.ok) { await __NEXTAUTH._getSession({ event: 'storage' }) }
return {
error,
status: res.status,
ok: res.ok,
url: error ? null : data.url
} as any
}
/**
* Signs the user out, by removing the session cookie.
* Automatically adds the CSRF token to the request.
*
* [Documentation](https://next-auth.js.org/getting-started/client#signout)
*/
export async function signOut<R extends boolean = true> (
options?: SignOutParams<R>
): Promise<R extends true ? undefined : SignOutResponse> {
const { callbackUrl = window.location.href } = options ?? {}
const baseUrl = apiBaseUrl(__NEXTAUTH)
const fetchOptions = {
method: 'post',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
// @ts-expect-error: Internal
body: new URLSearchParams({
csrfToken: await getCsrfToken(),
callbackUrl,
json: true
})
}
const res = await fetch(`${baseUrl}/signout`, fetchOptions)
const data = await res.json()
broadcast.post({ event: 'session', data: { trigger: 'signout' } })
if (options?.redirect ?? true) {
const url = data.url ?? callbackUrl
window.location.href = url
// If url contains a hash, the browser does not reload the page. We reload manually
if (url.includes('#')) { window.location.reload() }
// @ts-expect-error: Internal
return
}
await __NEXTAUTH._getSession({ event: 'storage' })
return data
}
export function SessionProviderPlugin (options: SessionProviderProps): Plugin {
return {
install (app) {
const { basePath } = options
if (basePath) { __NEXTAUTH.basePath = basePath }
/**
* If session was `null`, there was an attempt to fetch it,
* but it failed, but we still treat it as a valid initial value.
*/
const hasInitialSession = options.session !== undefined
/** If session was passed, initialize as already synced */
__NEXTAUTH._lastSync = hasInitialSession ? now() : 0
if (hasInitialSession) { __NEXTAUTH._session = options.session }
const session = ref(options.session)
/** If session was passed, initialize as not loading */
const loading = ref(!hasInitialSession)
__NEXTAUTH._getSession = async ({ event } = {}) => {
try {
const storageEvent = event === 'storage'
// We should always update if we don't have a client session yet
// or if there are events from other tabs/windows
if (storageEvent || __NEXTAUTH._session === undefined) {
__NEXTAUTH._lastSync = now()
__NEXTAUTH._session = await getSession({
broadcast: !storageEvent
})
session.value = __NEXTAUTH._session
return
}
if (
// If there is no time defined for when a session should be considered
// stale, then it's okay to use the value we have until an event is
// triggered which updates it
!event ||
// If the client doesn't have a session then we don't need to call
// the server to check if it does (if they have signed in via another
// tab or window that will come through as a "stroage" event
// event anyway)
__NEXTAUTH._session === null ||
// Bail out early if the client session is not stale yet
now() < __NEXTAUTH._lastSync
) { return }
// An event or session staleness occurred, update the client session.
__NEXTAUTH._lastSync = now()
__NEXTAUTH._session = await getSession()
session.value = __NEXTAUTH._session
} catch (error) {
logger.error('CLIENT_SESSION_ERROR', error as Error)
} finally {
loading.value = false
}
}
__NEXTAUTH._getSession()
const { refetchOnWindowFocus = true } = options
// Listen for when the page is visible, if the user switches tabs
// and makes our tab visible again, re-fetch the session, but only if
// this feature is not disabled.
const visibilityHandler = () => {
if (refetchOnWindowFocus && document.visibilityState === 'visible') { __NEXTAUTH._getSession({ event: 'visibilitychange' }) }
}
document.addEventListener('visibilitychange', visibilityHandler, false)
const unsubscribeFromBroadcast = broadcast.receive(() =>
__NEXTAUTH._getSession({ event: 'storage' })
)
const { refetchInterval } = options
let refetchIntervalTimer: NodeJS.Timer
if (refetchInterval) {
refetchIntervalTimer = setInterval(() => {
if (__NEXTAUTH._session) { __NEXTAUTH._getSession({ event: 'poll' }) }
}, refetchInterval * 1000)
}
const originalUnmount = app.unmount
app.unmount = function nextAuthUnmount () {
document.removeEventListener('visibilitychange', visibilityHandler, false)
unsubscribeFromBroadcast?.()
clearInterval(refetchIntervalTimer)
__NEXTAUTH._lastSync = 0
__NEXTAUTH._session = undefined
__NEXTAUTH._getSession = () => {}
originalUnmount()
}
const status = computed(() => loading.value ? 'loading' : session.value ? 'authenticated' : 'unauthenticated')
const value = reactive({
data: session,
status
})
app.provide('SessionKey', value)
}
}
}
/**
* Vue Composable that gives you access
* to the logged in user's session data.
*
* [Documentation](https://next-auth.js.org/getting-started/client#usesession)
*/
export function useSession (): {
data: Ref<SessionProviderProps['session']>;
status: Ref<string>;
} {
if (typeof window === 'undefined') {
return {
data: ref(null),
status: ref('loading')
}
}
const value = inject<{
data: SessionProviderProps['session']
status: string
}>('SessionKey')
if (!value) {
throw new Error('Could not resolve provided session value')
}
const { data, status } = toRefs(value)
return {
data,
status
}
}

View File

@@ -1,115 +0,0 @@
import type { Adapter } from 'next-auth/adapters'
import type { EventCallbacks, LoggerInstance } from 'next-auth'
/**
* Same as the default `Error`, but it is JSON serializable.
* @source https://iaincollins.medium.com/error-handling-in-javascript-a6172ccdf9af
*/
export class UnknownError extends Error {
code: string
constructor (error: Error | string) {
super((error as Error)?.message ?? error)
this.name = 'UnknownError'
this.code = (error as any).code
if (error instanceof Error) { this.stack = error.stack }
}
toJSON () {
return {
name: this.name,
message: this.message,
stack: this.stack
}
}
}
export class OAuthCallbackError extends UnknownError {
name = 'OAuthCallbackError'
}
/**
* Thrown when an Email address is already associated with an account
* but the user is trying an OAuth account that is not linked to it.
*/
export class AccountNotLinkedError extends UnknownError {
name = 'AccountNotLinkedError'
}
export class MissingAPIRoute extends UnknownError {
name = 'MissingAPIRouteError'
code = 'MISSING_NEXTAUTH_API_ROUTE_ERROR'
}
export class MissingSecret extends UnknownError {
name = 'MissingSecretError'
code = 'NO_SECRET'
}
export class MissingAuthorize extends UnknownError {
name = 'MissingAuthorizeError'
code = 'CALLBACK_CREDENTIALS_HANDLER_ERROR'
}
export class MissingAdapter extends UnknownError {
name = 'MissingAdapterError'
code = 'EMAIL_REQUIRES_ADAPTER_ERROR'
}
export class UnsupportedStrategy extends UnknownError {
name = 'UnsupportedStrategyError'
code = 'CALLBACK_CREDENTIALS_JWT_ERROR'
}
type Method = (...args: any[]) => Promise<any>
export function upperSnake (s: string) {
return s.replace(/([A-Z])/g, '_$1').toUpperCase()
}
export function capitalize (s: string) {
return `${s[0].toUpperCase()}${s.slice(1)}`
}
/**
* Wraps an object of methods and adds error handling.
*/
export function eventsErrorHandler (
methods: Partial<EventCallbacks>,
logger: LoggerInstance
): Partial<EventCallbacks> {
return Object.keys(methods).reduce<any>((acc, name) => {
acc[name] = async (...args: any[]) => {
try {
const method: Method = methods[name as keyof Method]
return await method(...args)
} catch (e) {
logger.error(`${upperSnake(name)}_EVENT_ERROR`, e as Error)
}
}
return acc
}, {})
}
/** Handles adapter induced errors. */
export function adapterErrorHandler (
adapter: Adapter | undefined,
logger: LoggerInstance
): Adapter | undefined {
if (!adapter) { return }
return Object.keys(adapter).reduce<any>((acc, name) => {
acc[name] = async (...args: any[]) => {
try {
logger.debug(`adapter_${name}`, { args })
const method: Method = adapter[name as keyof Method]
return await method(...args)
} catch (error) {
logger.error(`adapter_error_${name}`, error as Error)
const e = new UnknownError(error as Error)
e.name = `${capitalize(name)}Error`
throw e
}
}
return acc
}, {})
}

View File

@@ -1,113 +0,0 @@
import { UnknownError } from './errors'
// TODO: better typing
/** Makes sure that error is always serializable */
function formatError (o: unknown): unknown {
if (o instanceof Error && !(o instanceof UnknownError)) { return { message: o.message, stack: o.stack, name: o.name } }
if (hasErrorProperty(o)) {
o.error = formatError(o.error) as Error
o.message = o.message ?? o.error.message
}
return o
}
function hasErrorProperty (
x: unknown
): x is { error: Error; [key: string]: unknown } {
return !!(x as any)?.error
}
export type WarningCode =
| 'NEXTAUTH_URL'
| 'NO_SECRET'
| 'TWITTER_OAUTH_2_BETA'
| 'DEBUG_ENABLED'
/**
* Override any of the methods, and the rest will use the default logger.
*
* [Documentation](https://next-auth.js.org/configuration/options#logger)
*/
export interface LoggerInstance extends Record<string, Function> {
warn: (code: WarningCode) => void
error: (
code: string,
/**
* Either an instance of (JSON serializable) Error
* or an object that contains some debug information.
* (Error is still available through `metadata.error`)
*/
metadata: Error | { error: Error; [key: string]: unknown }
) => void
debug: (code: string, metadata: unknown) => void
}
const _logger: LoggerInstance = {
error (code, metadata) {
metadata = formatError(metadata) as Error
console.error(
`[next-auth][error][${code}]`,
`\nhttps://next-auth.js.org/errors#${code.toLowerCase()}`,
metadata.message,
metadata
)
},
warn (code) {
console.warn(
`[next-auth][warn][${code}]`,
`\nhttps://next-auth.js.org/warnings#${code.toLowerCase()}`
)
},
debug (code, metadata) {
// eslint-disable-next-line no-console
console.log(`[next-auth][debug][${code}]`, metadata)
}
}
/**
* Override the built-in logger with user's implementation.
* Any `undefined` level will use the default logger.
*/
export function setLogger (
newLogger: Partial<LoggerInstance> = {},
debug?: boolean
) {
// Turn off debug logging if `debug` isn't set to `true`
if (!debug) { _logger.debug = () => {} }
if (newLogger.error) { _logger.error = newLogger.error }
if (newLogger.warn) { _logger.warn = newLogger.warn }
if (newLogger.debug) { _logger.debug = newLogger.debug }
}
export default _logger
/** Serializes client-side log messages and sends them to the server */
export function proxyLogger (
logger: LoggerInstance = _logger,
basePath?: string
): LoggerInstance {
try {
if (typeof window === 'undefined') { return logger }
const clientLogger: Record<string, unknown> = {}
for (const level in logger) {
clientLogger[level] = (code: string, metadata: Error) => {
_logger[level](code, metadata) // Logs to console
if (level === 'error') {
metadata = formatError(metadata) as Error
}(metadata as any).client = true
const url = `${basePath}/_log`
const body = new URLSearchParams({ level, code, ...(metadata as any) })
if (navigator.sendBeacon) { return navigator.sendBeacon(url, body) }
return fetch(url, { method: 'POST', body, keepalive: true })
}
}
return clientLogger as unknown as LoggerInstance
} catch {
return _logger
}
}

View File

@@ -1,34 +0,0 @@
export interface InternalUrl {
/** @default "http://localhost:3000" */
origin: string
/** @default "localhost:3000" */
host: string
/** @default "/api/auth" */
path: string
/** @default "http://localhost:3000/api/auth" */
base: string
/** @default "http://localhost:3000/api/auth" */
toString: () => string
}
/** Returns an `URL` like object to make requests/redirects from server-side */
export default function parseUrl (url?: string): InternalUrl {
const defaultUrl = new URL('http://localhost:3000/api/auth')
if (url && !url.startsWith('http')) { url = `https://${url}` }
const _url = new URL(url ?? defaultUrl)
const path = (_url.pathname === '/' ? defaultUrl.pathname : _url.pathname)
// Remove trailing slash
.replace(/\/$/, '')
const base = `${_url.origin}${path}`
return {
origin: _url.origin,
host: _url.host,
path,
base,
toString: () => base
}
}

View File

@@ -1,7 +0,0 @@
// @ts-expect-error: Nuxt auto-import
import { defineNuxtPlugin } from '#app'
import { SessionProviderPlugin } from './client'
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.use(SessionProviderPlugin({}))
})

View File

@@ -1,93 +0,0 @@
import type { NextAuthAction, NextAuthOptions, Session } from 'next-auth'
import type { RequestInternal } from 'next-auth/core'
import { NextAuthHandler } from 'next-auth/core'
import {
appendHeader,
defineEventHandler,
isMethod,
sendRedirect,
setCookie,
readBody,
parseCookies,
getQuery
} from 'h3'
import type { H3Event } from 'h3'
export function NextAuthNuxtHandler (options: NextAuthOptions) {
return defineEventHandler(async (event) => {
// Catch-all route params in Nuxt goes to the underscore property
const nextauth = event.context.params._.split('/')
const req: RequestInternal | Request = {
host: process.env.NEXTAUTH_URL,
body: undefined,
query: getQuery(event),
headers: event.req.headers,
method: event.req.method,
cookies: parseCookies(event),
action: nextauth[0] as NextAuthAction,
providerId: nextauth[1],
error: nextauth[1]
}
if (isMethod(event, 'POST')) {
req.body = await readBody(event)
}
const response = await NextAuthHandler({
req,
options
})
const { headers, cookies, body, redirect, status = 200 } = response
event.res.statusCode = status
headers?.forEach((header) => {
appendHeader(event, header.key, header.value)
})
cookies?.forEach((cookie) => {
setCookie(event, cookie.name, cookie.value, cookie.options)
})
if (redirect) {
if (isMethod(event, 'POST')) {
const body = await readBody(event)
if (body?.json !== 'true') { await sendRedirect(event, redirect, 302) }
return {
url: redirect
}
} else {
await sendRedirect(event, redirect, 302)
}
}
return body
})
}
export async function getServerSession (
event: H3Event,
options: NextAuthOptions
): Promise<Session | null> {
options.secret = process.env.NEXTAUTH_SECRET
const session = await NextAuthHandler<Session>({
req: {
host: process.env.NEXTAUTH_URL,
action: 'session',
method: 'GET',
cookies: parseCookies(event),
headers: event.req.headers
},
options
})
const { body } = session
if (body && Object.keys(body).length) {
return body
}
return null
}

View File

@@ -1,78 +0,0 @@
import type { Session } from 'next-auth'
import type { BuiltInProviderType, ProviderType } from 'next-auth/providers'
export interface UseSessionOptions<R extends boolean> {
required: R
/** Defaults to `signIn` */
onUnauthenticated?: () => void
}
/**
* Util type that matches some strings literally, but allows any other string as well.
* @source https://github.com/microsoft/TypeScript/issues/29729#issuecomment-832522611
*/
export type LiteralUnion<T extends U, U = string> =
| T
| (U & Record<never, never>)
export interface ClientSafeProvider {
id: LiteralUnion<BuiltInProviderType>
name: string
type: ProviderType
signinUrl: string
callbackUrl: string
}
export interface SignInOptions extends Record<string, unknown> {
/**
* Defaults to the current URL.
* @docs https://next-auth.js.org/getting-started/client#specifying-a-callbackurl
*/
callbackUrl?: string
/** @docs https://next-auth.js.org/getting-started/client#using-the-redirect-false-option */
redirect?: boolean
}
export interface SignInResponse {
error: string | undefined
status: number
ok: boolean
url: string | null
}
/** Match `inputType` of `new URLSearchParams(inputType)` */
export type SignInAuthorizationParams =
| string
| string[][]
| Record<string, string>
| URLSearchParams
/** @docs https://next-auth.js.org/getting-started/client#using-the-redirect-false-option-1 */
export interface SignOutResponse {
url: string
}
export interface SignOutParams<R extends boolean = true> {
/** @docs https://next-auth.js.org/getting-started/client#specifying-a-callbackurl-1 */
callbackUrl?: string
/** @docs https://next-auth.js.org/getting-started/client#using-the-redirect-false-option-1 */
redirect?: R
}
/** @docs: https://next-auth.js.org/getting-started/client#options */
export interface SessionProviderProps {
// children: React.ReactNode
session?: Session | null
baseUrl?: string
basePath?: string
/**
* A time interval (in seconds) after which the session will be re-fetched.
* If set to `0` (default), the session is not polled.
*/
refetchInterval?: number
/**
* `SessionProvider` automatically refetches the session when the user switches between windows.
* This option activates this behaviour if set to `true` (default).
*/
refetchOnWindowFocus?: boolean
}

View File

@@ -1,4 +1,4 @@
{
// https://v3.nuxtjs.org/concepts/typescript
"extends": "./playground/.nuxt/tsconfig.json"
"extends": "./.nuxt/tsconfig.json",
}

View File

@@ -1,4 +0,0 @@
versioned_sidebars
versioned_docs
node_modules
.docusaurus

View File

@@ -3,11 +3,11 @@ id: faq
title: Frequently Asked Questions
---
## About NextAuth.js
## About Auth.js
### Is NextAuth.js commercial software?
### Is Auth.js commercial software?
NextAuth.js is an open source project built by individual contributors.
Auth.js is an open source project built by individual contributors.
It is not commercial software and is not associated with a commercial organization.
@@ -17,29 +17,28 @@ It is not commercial software and is not associated with a commercial organizati
<details>
<summary>
<h3 style={{display:"inline-block"}}>What databases does NextAuth.js support?</h3>
<h3 style={{display:"inline-block"}}>What databases does Auth.js support?</h3>
</summary>
<p>
You can use NextAuth.js with MySQL, MariaDB, Postgres, MongoDB and SQLite or without a database. (See our [using a database adapter guide](/guides/adapters/using-a-database-adapter)).
You can use Auth.js with MySQL, MariaDB, Postgres, MongoDB and SQLite or without a database. (See our [using a database adapter guide](/guides/adapters/using-a-database-adapter)).
You can use also NextAuth.js with any database using a custom database adapter, or by using a custom credentials authentication provider - e.g. to support signing in with a username and password stored in an existing database.
You can use also Auth.js with any database using a custom database adapter, or by using a custom credentials authentication provider - e.g. to support signing in with a username and password stored in an existing database.
</p>
</details>
<details>
<summary>
<h3 style={{display:"inline-block"}}>What authentication services does NextAuth.js support?</h3>
<h3 style={{display:"inline-block"}}>What authentication services does Auth.js support?</h3>
</summary>
<p>
<p>NextAuth.js includes built-in support for signing in with&nbsp;
--------- DISPLAY PROVIDERS HERE ----------
<p>Auth.js includes built-in support for signing in with&nbsp;
(See also: <a href="/reference/providers/oauth-builtin">Providers</a>)
</p>
NextAuth.js also supports email for passwordless sign in, which is useful for account recovery or for people who are not able to use an account with the configured OAuth services (e.g. due to service outage, account suspension or otherwise becoming locked out of an account).
Auth.js also supports email for passwordless sign in, which is useful for account recovery or for people who are not able to use an account with the configured OAuth services (e.g. due to service outage, account suspension or otherwise becoming locked out of an account).
You can also use a custom based provider to support signing in with a username and password stored in an external database and/or using two factor authentication.
@@ -48,43 +47,43 @@ You can also use a custom based provider to support signing in with a username a
<details>
<summary>
<h3 style={{display:"inline-block"}}>Does NextAuth.js support signing in with a username and password?</h3>
<h3 style={{display:"inline-block"}}>Does Auth.js support signing in with a username and password?</h3>
</summary>
<p>
NextAuth.js is designed to avoid the need to store passwords for user accounts.
Auth.js is designed to avoid the need to store passwords for user accounts.
If you have an existing database of usernames and passwords, you can use a custom credentials provider to allow signing in with a username and password stored in an existing database.
_If you use a custom credentials provider user accounts will not be persisted in a database by NextAuth.js (even if one is configured). The option to use JSON Web Tokens for session tokens (which allow sign in without using a session database) must be enabled to use a custom credentials provider._
_If you use a custom credentials provider user accounts will not be persisted in a database by Auth.js (even if one is configured). The option to use JSON Web Tokens for session tokens (which allow sign in without using a session database) must be enabled to use a custom credentials provider._
</p>
</details>
<details>
<summary>
<h3 style={{display:"inline-block"}}>Can I use NextAuth.js with a website that does not use Next.js?</h3>
<h3 style={{display:"inline-block"}}>Can I use Auth.js with a website that does not use Next.js?</h3>
</summary>
<p>
NextAuth.js is designed for use with Next.js and Serverless.
Auth.js is designed for use with Next.js and Serverless.
If you are using a different framework for your website, you can create a website that handles sign in with Next.js and then access those sessions on a website that does not use Next.js as long as the websites are on the same domain.
If you use NextAuth.js on a website with a different subdomain then the rest of your website (e.g. `auth.example.com` vs `www.example.com`) you will need to set a custom cookie domain policy for the Session Token cookie. (See also: [Cookies](/reference/configuration/auth-config#cookies))
If you use Auth.js on a website with a different subdomain then the rest of your website (e.g. `auth.example.com` vs `www.example.com`) you will need to set a custom cookie domain policy for the Session Token cookie. (See also: [Cookies](/reference/configuration/auth-config#cookies))
NextAuth.js does not currently support automatically signing into sites on different top level domains (e.g. `www.example.com` vs `www.example.org`) using a single session.
Auth.js does not currently support automatically signing into sites on different top level domains (e.g. `www.example.com` vs `www.example.org`) using a single session.
</p>
</details>
<details>
<summary>
<h3 style={{display:"inline-block"}}>Can I use NextAuth.js with React Native?</h3>
<h3 style={{display:"inline-block"}}>Can I use Auth.js with React Native?</h3>
</summary>
<p>
NextAuth.js is designed as a secure, confidential client and implements a server side authentication flow.
Auth.js is designed as a secure, confidential client and implements a server side authentication flow.
It is not intended to be used in native applications on desktop or mobile applications, which typically implement public clients (e.g. with client / secrets embedded in the application).
@@ -93,7 +92,7 @@ It is not intended to be used in native applications on desktop or mobile applic
<details>
<summary>
<h3 style={{display:"inline-block"}}>Is NextAuth.js supporting TypeScript?</h3>
<h3 style={{display:"inline-block"}}>Is Auth.js supporting TypeScript?</h3>
</summary>
<p>
@@ -104,7 +103,7 @@ Yes! Check out the [TypeScript docs](/getting-started/typescript)
<details>
<summary>
<h3 style={{display:"inline-block"}}>Is NextAuth.js compatible with Next.js 12 Middleware?</h3>
<h3 style={{display:"inline-block"}}>Is Auth.js compatible with Next.js 12 Middleware?</h3>
</summary>
<p>
@@ -119,11 +118,11 @@ Yes! Check out the [TypeScript docs](/getting-started/typescript)
<details>
<summary>
<h3 style={{display:"inline-block"}}>What databases are supported by NextAuth.js?</h3>
<h3 style={{display:"inline-block"}}>What databases are supported by Auth.js?</h3>
</summary>
<p>
NextAuth.js can be used with MySQL, Postgres, MongoDB, SQLite and compatible databases (e.g. MariaDB, Amazon Aurora, Amazon DocumentDB…) or with no database.
Auth.js can be used with MySQL, Postgres, MongoDB, SQLite and compatible databases (e.g. MariaDB, Amazon Aurora, Amazon DocumentDB…) or with no database.
It also provides an Adapter API which allows you to connect it to any database.
@@ -132,15 +131,15 @@ It also provides an Adapter API which allows you to connect it to any database.
<details>
<summary>
<h3 style={{display:"inline-block"}}>What does NextAuth.js use databases for?</h3>
<h3 style={{display:"inline-block"}}>What does Auth.js use databases for?</h3>
</summary>
<p>
Databases in NextAuth.js are used for persisting users, OAuth accounts, email sign in tokens and sessions.
Databases in Auth.js are used for persisting users, OAuth accounts, email sign in tokens and sessions.
Specifying a database is optional if you don't need to persist user data or support email sign in. If you don't specify a database then JSON Web Tokens will be enabled for session storage and used to store session data.
If you are using a database with NextAuth.js, you can still explicitly enable JSON Web Tokens for sessions (instead of using database sessions).
If you are using a database with Auth.js, you can still explicitly enable JSON Web Tokens for sessions (instead of using database sessions).
</p>
</details>
@@ -151,9 +150,9 @@ If you are using a database with NextAuth.js, you can still explicitly enable JS
</summary>
<p>
- Using NextAuth.js without a database works well for internal tools - where you need to control who is able to sign in, but when you do not need to create user accounts for them in your application.
- Using Auth.js without a database works well for internal tools - where you need to control who is able to sign in, but when you do not need to create user accounts for them in your application.
- Using NextAuth.js with a database is usually a better approach for a consumer facing application where you need to persist accounts (e.g. for billing, to contact customers, etc).
- Using Auth.js with a database is usually a better approach for a consumer facing application where you need to persist accounts (e.g. for billing, to contact customers, etc).
</p>
</details>
@@ -183,18 +182,18 @@ Parts of this section has been moved to its [own page](/getting-started/security
</summary>
<p>
NextAuth.js provides a solution for authentication, session management and user account creation.
Auth.js provides a solution for authentication, session management and user account creation.
NextAuth.js records Refresh Tokens and Access Tokens on sign in (if supplied by the provider) and it will pass them, along with the User ID, Provider and Provider Account ID, to either:
Auth.js records Refresh Tokens and Access Tokens on sign in (if supplied by the provider) and it will pass them, along with the User ID, Provider and Provider Account ID, to either:
1. A database - if a database connection string is provided
2. The JSON Web Token callback - if JWT sessions are enabled (e.g. if no database specified)
You can then look them up from the database or persist them to the JSON Web Token.
Note: NextAuth.js does not currently handle Access Token rotation for OAuth providers for you, however you can check out [this tutorial](/guides/basics/refresh-token-rotation) if you want to implement it.
Note: Auth.js does not currently handle Access Token rotation for OAuth providers for you, however you can check out [this tutorial](/guides/basics/refresh-token-rotation) if you want to implement it.
We also have an [example repository](https://github.com/nextauthjs/next-auth-refresh-token-example) / project based upon NextAuth.js v4 where we demonstrate how to use a refresh token to refresh the provided access token.
We also have an [example repository](https://github.com/nextauthjs/next-auth-refresh-token-example) / project based upon Auth.js v4 where we demonstrate how to use a refresh token to refresh the provided access token.
</p>
</details>
@@ -211,13 +210,13 @@ When an email address is associated with an OAuth account it does not necessaril
With automatic account linking on sign in, this can be exploited by bad actors to hijack accounts by creating an OAuth account associated with the email address of another user.
For this reason it is not secure to automatically link accounts between arbitrary providers on sign in, which is why this feature is generally not provided by authentication service and is not provided by NextAuth.js.
For this reason it is not secure to automatically link accounts between arbitrary providers on sign in, which is why this feature is generally not provided by authentication service and is not provided by Auth.js.
Automatic account linking is seen on some sites, sometimes insecurely. It can be technically possible to do automatic account linking securely if you trust all the providers involved to ensure they have securely verified the email address associated with the account, but requires placing trust (and transferring the risk) to those providers to handle the process securely.
Examples of scenarios where this is secure include with an OAuth provider you control (e.g. that only authorizes users internal to your organization) or with a provider you explicitly trust to have verified the users email address.
Automatic account linking is not a planned feature of NextAuth.js, however there is scope to improve the user experience of account linking and of handling this flow, in a secure way. Typically this involves providing a fallback option to sign in via email, which is already possible (and recommended), but the current implementation of this flow could be improved on.
Automatic account linking is not a planned feature of Auth.js, however there is scope to improve the user experience of account linking and of handling this flow, in a secure way. Typically this involves providing a fallback option to sign in via email, which is already possible (and recommended), but the current implementation of this flow could be improved on.
Providing support for secure account linking and unlinking of additional providers - which can only be done if a user is already signed in already - was originally a feature in v1.x but has not been present since v2.0, is planned to return in a future release.
@@ -230,13 +229,13 @@ Providing support for secure account linking and unlinking of additional provide
<details>
<summary>
<h3 style={{display:"inline-block"}}>Why doesn't NextAuth.js support [a particular feature]?</h3>
<h3 style={{display:"inline-block"}}>Why doesn't Auth.js support [a particular feature]?</h3>
</summary>
<p>
NextAuth.js is an open source project built by individual contributors who are volunteers writing code and providing support in their spare time.
Auth.js is an open source project built by individual contributors who are volunteers writing code and providing support in their spare time.
If you would like NextAuth.js to support a particular feature, the best way to help make it happen is to raise a feature request describing the feature and offer to work with other contributors to develop and test it.
If you would like Auth.js to support a particular feature, the best way to help make it happen is to raise a feature request describing the feature and offer to work with other contributors to develop and test it.
If you are not able to develop a feature yourself, you can offer to sponsor someone to work on it.
@@ -249,7 +248,7 @@ If you are not able to develop a feature yourself, you can offer to sponsor some
</summary>
<p>
Product design decisions on NextAuth.js are made by core team members.
Product design decisions on Auth.js are made by core team members.
You can raise suggestions as feature requests / requests for enhancement.
@@ -266,11 +265,11 @@ Ultimately if your request is not accepted or is not actively in development, yo
<details>
<summary>
<h3>Does NextAuth.js use JSON Web Tokens?</h3>
<h3>Does Auth.js use JSON Web Tokens?</h3>
</summary>
<p>
NextAuth.js by default uses JSON Web Tokens for saving the user's session. However, if you use a [database adapter](/guides/adapters/using-a-database-adapter), the database will be used to persist the user's session. You can force the usage of JWT when using a database [through the configuration options](/reference/configuration/auth-config#session). Since v4 all our JWT tokens are now encrypted by default with A256GCM.
Auth.js by default uses JSON Web Tokens for saving the user's session. However, if you use a [database adapter](/guides/adapters/using-a-database-adapter), the database will be used to persist the user's session. You can force the usage of JWT when using a database [through the configuration options](/reference/configuration/auth-config#session). Since v4 all our JWT tokens are now encrypted by default with A256GCM.
</p>
</details>
@@ -285,7 +284,7 @@ JSON Web Tokens can be used for session tokens, but are also used for lots of ot
- Advantages of using a JWT as a session token include that they do not require a database to store sessions, this can be faster and cheaper to run and easier to scale.
- JSON Web Tokens in NextAuth.js are secured using cryptographic encryption (JWE) to store the included information directly in a JWT session token. You may then use the token to pass information between services and APIs on the same domain without having to contact a database to verify the included information.
- JSON Web Tokens in Auth.js are secured using cryptographic encryption (JWE) to store the included information directly in a JWT session token. You may then use the token to pass information between services and APIs on the same domain without having to contact a database to verify the included information.
- You can use JWT to securely store information you do not mind the client knowing even without encryption, as the JWT is stored in a server-readable-only cookie so data in the JWT is not accessible to third party JavaScript running on your site.
@@ -302,7 +301,7 @@ JSON Web Tokens can be used for session tokens, but are also used for lots of ot
Shorter session expiry times are used when using JSON Web Tokens as session tokens to allow sessions to be invalidated sooner and simplify this problem.
NextAuth.js client includes advanced features to mitigate the downsides of using shorter session expiry times on the user experience, including automatic session token rotation, optionally sending keep alive messages to prevent short lived sessions from expiring if there is an window or tab open, background re-validation, and automatic tab/window syncing that keeps sessions in sync across windows any time session state changes or a window or tab gains or loses focus.
Auth.js client includes advanced features to mitigate the downsides of using shorter session expiry times on the user experience, including automatic session token rotation, optionally sending keep alive messages to prevent short lived sessions from expiring if there is an window or tab open, background re-validation, and automatic tab/window syncing that keeps sessions in sync across windows any time session state changes or a window or tab gains or loses focus.
- As with database session tokens, JSON Web Tokens are limited in the amount of data you can store in them. There is typically a limit of around 4096 bytes per cookie, though the exact limit varies between browsers, proxies and hosting services. If you want to support most browsers, then do not exceed 4096 bytes per cookie. If you want to save more data, you will need to persist your sessions in a database (Source: [browsercookielimits.iain.guru](http://browsercookielimits.iain.guru/))
@@ -314,7 +313,7 @@ JSON Web Tokens can be used for session tokens, but are also used for lots of ot
Avoid storing any data in a token that might be problematic if it were to be decrypted in the future.
- If you do not explicitly specify a secret for for NextAuth.js, existing sessions will be invalidated any time your NextAuth.js configuration changes, as NextAuth.js will default to an auto-generated secret. Since v4 this only impacts development and generating a secret is required in production.
- If you do not explicitly specify a secret for for Auth.js, existing sessions will be invalidated any time your Auth.js configuration changes, as Auth.js will default to an auto-generated secret. Since v4 this only impacts development and generating a secret is required in production.
</p>
</details>
@@ -329,7 +328,7 @@ By default tokens are not signed (JWS) but are encrypted (JWE). Since v4 we have
You can specify other valid algorithms - [as specified in RFC 7518](https://tools.ietf.org/html/rfc7517) - with either a secret (for symmetric encryption) or a public/private key pair (for asymmetric encryption).
NextAuth.js will generate keys for you, but this will generate a warning at start up.
Auth.js will generate keys for you, but this will generate a warning at start up.
Using explicit public/private keys for signing is strongly recommended.
@@ -338,11 +337,11 @@ Using explicit public/private keys for signing is strongly recommended.
<details>
<summary>
<h3>What signing and encryption standards does NextAuth.js support?</h3>
<h3>What signing and encryption standards does Auth.js support?</h3>
</summary>
<p>
NextAuth.js includes a largely complete implementation of JSON Object Signing and Encryption (JOSE):
Auth.js includes a largely complete implementation of JSON Object Signing and Encryption (JOSE):
- [RFC 7515 - JSON Web Signature (JWS)](https://tools.ietf.org/html/rfc7515)
- [RFC 7516 - JSON Web Encryption (JWE)](https://tools.ietf.org/html/rfc7516)

View File

@@ -2,13 +2,13 @@
title: How OAuth works
---
Authentication Providers in **NextAuth.js** are OAuth definitions that allow your users to sign in with their favorite preexisting logins. You can use any of our many predefined providers, or write your own custom OAuth configuration.
Authentication Providers in **Auth.js** are OAuth definitions that allow your users to sign in with their favorite preexisting logins. You can use any of our many predefined providers, or write your own custom OAuth configuration.
- [Using a built-in OAuth Provider](#built-in-providers) (e.g Github, Twitter, Google, etc...)
- [Using a custom OAuth Provider](#using-a-custom-provider)
:::note
NextAuth.js is designed to work with any OAuth service, it supports **OAuth 1.0**, **1.0A**, **2.0** and **OpenID Connect** and has built-in support for most popular sign-in services.
Auth.js is designed to work with any OAuth service, it supports **OAuth 1.0**, **1.0A**, **2.0** and **OpenID Connect** and has built-in support for most popular sign-in services.
:::
Without going into too much detail, the OAuth flow generally has 6 parts:

View File

@@ -22,20 +22,20 @@ Special thanks to Lori Karikari for creating most of the original provider confi
## Other contributors
NextAuth.js as it exists today has been possible thanks to the work of many individual contributors.
Auth.js as it exists today has been possible thanks to the work of many individual contributors.
Thank you to the [dozens of individual contributors](https://github.com/nextauthjs/next-auth/graphs/contributors) who have help shaped NextAuth.js.
Thank you to the [dozens of individual contributors](https://github.com/nextauthjs/next-auth/graphs/contributors) who have help shaped Auth.js.
## Open Collective
You can find NextAuth.js on Open Collective. We are very thankful for all of our existing contributors and would be delighted if you or your company would decide to join them.
You can find Auth.js on Open Collective. We are very thankful for all of our existing contributors and would be delighted if you or your company would decide to join them.
More information can be found at: https://opencollective.com/nextauth
## History
- NextAuth.js was originally developed by <a href="https://github.com/iaincollins">Iain Collins</a> in 2016 for Next.js.
- Auth.js was originally developed by <a href="https://github.com/iaincollins">Iain Collins</a> in 2016 for Next.js.
- In 2020, NextAuth.js was rebuilt from the ground up to support Serverless, with support for MySQL, Postgres and MongoDB, JSON Web Tokens and built in support for over a dozen authentication providers.
- In 2020, Auth.js was rebuilt from the ground up to support Serverless, with support for MySQL, Postgres and MongoDB, JSON Web Tokens and built in support for over a dozen authentication providers.
- In 2021, efforts have started to move NextAuth.js to other frameworks and to support as many databases and providers as possible.
- In 2021, efforts have started to move Auth.js to other frameworks and to support as many databases and providers as possible.

View File

@@ -2,9 +2,9 @@
title: Introduction
---
## About NextAuth.js
## About Auth.js
NextAuth.js is a complete open-source authentication solution for [Next.js](http://nextjs.org/) applications.
Auth.js is a complete open-source authentication solution for [Next.js](http://nextjs.org/) applications.
It is designed from the ground up to support Next.js and Serverless.
@@ -25,7 +25,7 @@ Check our tutorials to see how easy it is to use Auth.js for authentication:
### Own your own data
NextAuth.js can be used with or without a database.
Auth.js can be used with or without a database.
- An open-source solution that allows you to keep control of your data
- Supports Bring Your Own Database (BYOD) and can be used with any database
@@ -50,6 +50,6 @@ Advanced options allow you to define your own routines to handle controlling wha
## Credits
NextAuth.js is an open-source project that is only possible [thanks to contributors](/contributors).
Auth.js is an open-source project that is only possible [thanks to contributors](/contributors).
If you would like to financially support the development of NextAuth.js, you can find more information on our [OpenCollective](https://opencollective.com/nextauth) page.
If you would like to financially support the development of Auth.js, you can find more information on our [OpenCollective](https://opencollective.com/nextauth) page.

View File

@@ -9,25 +9,25 @@ import startAppAndSignInImg from "./img/getting-started-app-start.png"
import githubAuthCredentials from "./img/getting-started-github-auth.png"
import nextAuthUserLoggedIn from "./img/getting-started-nextauth-success.png"
We know, authentication is hard. Is a rabbit hole and it's easy to get lost on it. The goal of making NextAuth.js is that you can add authentication easily to your project with just a few lines of code.
We know, authentication is hard. Is a rabbit hole and it's easy to get lost on it. The goal of making Auth.js is that you can add authentication easily to your project with just a few lines of code.
The easiest way is to setup NextAuth.js with an [OAuth](https://en.wikipedia.org/wiki/OAuth) provider. In this tutorial we'll be setting NextAuth.js in a **Next.js app** to be able to login with **Github**.
The easiest way is to setup Auth.js with an [OAuth](https://en.wikipedia.org/wiki/OAuth) provider. In this tutorial we'll be setting Auth.js in a **Next.js app** to be able to login with **Github**.
:::info
NextAuth.js comes with a long list of [built-in providers](/reference/providers/oauth-builtin) (Google, Facebook, Twitter, etc...) you can also integrate it with your own OAuth service easily by [building a custom provider](/guides/providers/custom-provider). NextAuth.js can integrate as well with other frameworks like SvelteKit and Gatsby.
Auth.js comes with a long list of [built-in providers](/reference/providers/oauth-builtin) (Google, Facebook, Twitter, etc...) you can also integrate it with your own OAuth service easily by [building a custom provider](/guides/providers/custom-provider). Auth.js can integrate as well with other frameworks like SvelteKit and Gatsby.
:::
## 1. Configuring NextAuth.js
## 1. Configuring Auth.js
### Creating the server config
To add NextAuth.js to a [**Next.js**](https://nextjs.org/) project, create the following [API route](https://nextjs.org/docs/api-routes/introduction):
To add Auth.js to a [**Next.js**](https://nextjs.org/) project, create the following [API route](https://nextjs.org/docs/api-routes/introduction):
```
pages/api/auth/[...nextauth].ts
```
This route will contain the **dynamic route handler** for NextAuth.js which describes your global auth configuration:
This route will contain the **dynamic route handler** for Auth.js which describes your global auth configuration:
```ts title="pages/api/auth/[...nextauth].js"
import NextAuth from "next-auth"
@@ -50,7 +50,7 @@ Behind the scenes this creates all the relevant OAuth API routes within `/api/au
- `/api/auth/singOut`
- etc...
can be handled by NextAuth.js. In this way, NextAuth.js stays in charge of handling the whole authentication request/response flow of your application for you.
can be handled by Auth.js. In this way, Auth.js stays in charge of handling the whole authentication request/response flow of your application for you.
You may notice there are some environment variables in the code example above. `GITHUB_ID` and `GITHUB_SECRET` are provided by the OAuth provider (in this case **Github**) see ["Configuring OAuth Provider"](/getting-started/oauth-tutorial#2-configuring-oauth-provider) section on how to get those.
@@ -63,7 +63,7 @@ $ openssl rand -base64 32
or https://generate-secret.vercel.app/32 to generate a random value for it.
:::info
NextAuth.js is extremely customizable, [our guides section](/guides/overview) will teach you how you can set it up to handle auth in different ways. All the possible configuration options are [listed here](/reference/configuration/auth-config).
Auth.js is extremely customizable, [our guides section](/guides/overview) will teach you how you can set it up to handle auth in different ways. All the possible configuration options are [listed here](/reference/configuration/auth-config).
:::
### Exposing the session via provider
@@ -93,7 +93,7 @@ Check our [client docs](/reference/react/) to learn all the available options fo
### Consuming the session via hooks
NextAuth.js exposes a [`useSession()`](/reference/react/#usesession) React Hook so that you can easily check if someone is signed in:
Auth.js exposes a [`useSession()`](/reference/react/#usesession) React Hook so that you can easily check if someone is signed in:
```ts title="pages/overview.tsx"
import { useSession, signIn, signOut } from "next-auth/react"
@@ -160,7 +160,7 @@ Ok, we have our Next.js app setup with NextAuth, however, if you run the app rig
When using OAuth you're asking for a third-party service (in this case Github, although it could be Google, Twitter, etc...) to handle user authentication for your app.
:::
We need to register our new Next.js app in Github, so that when NextAuth.js forwards the authorization requests to it, Github can recognize your application and prompt the user to sign in.
We need to register our new Next.js app in Github, so that when Auth.js forwards the authorization requests to it, Github can recognize your application and prompt the user to sign in.
<img src={creatingOauthAppImg} />
@@ -183,7 +183,7 @@ http://localhost:3000/api/auth/callback/github
```
:::info
NextAuth.js will already magically create this API endpoint for you when we start the application later. Note that because we're using Next.js, locally it starts our server on the port `3000`, hence the origin is `http://localhost:3000`.
Auth.js will already magically create this API endpoint for you when we start the application later. Note that because we're using Next.js, locally it starts our server on the port `3000`, hence the origin is `http://localhost:3000`.
:::
Next you'll be presented with the following screen which presents all the configuration for your new OAuth app. For now, let's we need two things from it: the **Client ID** and **Client Secret** for our new OAuth app:
@@ -206,7 +206,7 @@ GITHUB_SECRET=67890
Cool! We have finished the configuring our OAuth provider, now let's wire all together so we can finally see authentication working in our app!
:::info
As noted previously, NextAuth.js has built-in support for multiple OAuth providers, <a href="">here the full list</a>. You can also easily build your own in case the provider you need is not on the list.
As noted previously, Auth.js has built-in support for multiple OAuth providers, <a href="">here the full list</a>. You can also easily build your own in case the provider you need is not on the list.
Note that, for each provider, the configuration process will be similar to what we just did:
@@ -218,7 +218,7 @@ Note that, for each provider, the configuration process will be similar to what
## 3. Wiring all together
Finally, we just need to reference our **Client ID** and **Client Secret** we just generated in the previous in our NextAuth.js config. In this way the library will be able to use them when forwarding users to Github, and Github will be able to recognize the request as generated from our application:
Finally, we just need to reference our **Client ID** and **Client Secret** we just generated in the previous in our Auth.js config. In this way the library will be able to use them when forwarding users to Github, and Github will be able to recognize the request as generated from our application:
```ts title="pages/api/auth/[...nextauth].js"
import NextAuth from "next-auth"
@@ -244,18 +244,18 @@ You should see the following page:
<img src={startAppAndSignInImg} />
Click on "Sign in" and then on "Sign in with Github": NextAuth.js will redirect you to Github, and Github will recognize our app [that we just registered](#2-configuring-oauth-provider) and ask the user (in this case you) to enter its credentials to proceed:
Click on "Sign in" and then on "Sign in with Github": Auth.js will redirect you to Github, and Github will recognize our app [that we just registered](#2-configuring-oauth-provider) and ask the user (in this case you) to enter its credentials to proceed:
<img src={githubAuthCredentials} />
Once inserted and correct, Github will redirect the user to our app and NextAuth.js will take care of any further calls with Github to get access to the user profile and start a user sessions safely in the background:
Once inserted and correct, Github will redirect the user to our app and Auth.js will take care of any further calls with Github to get access to the user profile and start a user sessions safely in the background:
<img src={nextAuthUserLoggedIn} />
Great! We have completed the whole E2E authentication flow setup so that users can login in our application through Github!
:::info
You can create your own Sign In page instead of using the default one from NextAuth.js. You can learn how to do so in our dedicated guide for it.
You can create your own Sign In page instead of using the default one from Auth.js. You can learn how to do so in our dedicated guide for it.
:::
## 4. Deploying to production

View File

@@ -8,7 +8,7 @@ import checkPageImg from "./img/email-tutorial-check.png"
import mailboxImg from "./img/email-tutorial-mailbox.png"
import loggedInImg from "./img/email-tutorial-logged.png"
Aside from authenticating users in NextAuth.js via [OAuth](/getting-started/oauth-tutorial), you can also enable the option to authenticate them via "magic links". These are links that are sent to the user's email and when clicking on them they'll sign up the user automatically.
Aside from authenticating users in Auth.js via [OAuth](/getting-started/oauth-tutorial), you can also enable the option to authenticate them via "magic links". These are links that are sent to the user's email and when clicking on them they'll sign up the user automatically.
Adding support for signing in via email in addition to one or more OAuth services provides a way for users to sign in if they lose access to their OAuth account (e.g. if it is locked or deleted).
@@ -89,7 +89,7 @@ export default NextAuth({
Finally, we'll need to set up a database adapter to store verification tokens the Email Provider will emit when verifying users.
An **Adapter** in NextAuth.js connects your application to whatever database or backend system you want to use to store data for users, their accounts, sessions, etc...
An **Adapter** in Auth.js connects your application to whatever database or backend system you want to use to store data for users, their accounts, sessions, etc...
For this tutorial, we're going to use the **MongoDB** adapter, other any of the other adapters will work just fine.
@@ -137,7 +137,7 @@ if (process.env.NODE_ENV === "development") {
export default clientPromise
```
And now let's reference this new adapter from our NextAuth.js configuration file:
And now let's reference this new adapter from our Auth.js configuration file:
```diff title="pages/api/auth/[...nextauth].ts"
import NextAuth from "next-auth"

View File

@@ -2,19 +2,19 @@
title: Credentials authentication
---
NextAuth.js is built in a way that is flexible to integrate it with any authentication back-end you or your company may already have.
Auth.js is built in a way that is flexible to integrate it with any authentication back-end you or your company may already have.
This library has been designed to handle the user session client-wise, to support multiple authentication methods (OAuth, Email, etc...) so that you're not forced to run your own authentication service.
In case you already have an authentication service, you can use the Credentials Provider, which will just forward the credentials inserted by the user in the login form to your service.
For this tutorial, we're going to use [NextAuth.js example app](https://github.com/nextauthjs/next-auth-example) as a base.
For this tutorial, we're going to use [Auth.js example app](https://github.com/nextauthjs/next-auth-example) as a base.
:::warning
The functionality provided for credentials based authentication is intentionally limited to discourage use of passwords due to the inherent security risks associated with them and the additional complexity associated with supporting usernames and passwords.
:::
Integrating the Credentials Provider is as simple as initializing it in the NextAuth.js configuration file:
Integrating the Credentials Provider is as simple as initializing it in the Auth.js configuration file:
```ts title="pages/api/auth/[...nextauth].ts"
import NextAuth from "next-auth"

View File

@@ -2,7 +2,7 @@
title: TypeScript
---
NextAuth.js has its own type definitions to use in your TypeScript projects safely. Even if you don't use TypeScript, IDEs like VSCode will pick this up to provide you with a better developer experience. While you are typing, you will get suggestions about what certain objects/functions look like, and sometimes links to documentation, examples, and other valuable resources.
Auth.js has its own type definitions to use in your TypeScript projects safely. Even if you don't use TypeScript, IDEs like VSCode will pick this up to provide you with a better developer experience. While you are typing, you will get suggestions about what certain objects/functions look like, and sometimes links to documentation, examples, and other valuable resources.
Check out the example repository showcasing how to use `next-auth` on a Next.js application with TypeScript:
https://github.com/nextauthjs/next-auth-typescript-example

View File

@@ -2,17 +2,17 @@
title: Databases
---
NextAuth.js offers multiple database adapters. Check our guides on:
Auth.js offers multiple database adapters. Check our guides on:
- [using a database adapter](/guides/adapters/using-a-database-adapter)
- [creating your own](/guides/adapters/creating-a-database-adapter)
> As of **v4** NextAuth.js no longer ships with an adapter included by default. If you would like to persist any information, you need to install one of the many available adapters yourself. See the individual adapter documentation pages for more details.
> As of **v4** Auth.js no longer ships with an adapter included by default. If you would like to persist any information, you need to install one of the many available adapters yourself. See the individual adapter documentation pages for more details.
To learn more about databases in NextAuth.js and how they are used, check out [databases in the FAQ](/concepts/faq#databases).
To learn more about databases in Auth.js and how they are used, check out [databases in the FAQ](/concepts/faq#databases).
---
## How to use a database
See the [documentation for adapters](/reference/adapters/overview) for more information on advanced configuration, including how to use NextAuth.js with other databases using a [custom adapter](/guides/adapters/creating-a-database-adapter).
See the [documentation for adapters](/reference/adapters/overview) for more information on advanced configuration, including how to use Auth.js with other databases using a [custom adapter](/guides/adapters/creating-a-database-adapter).

View File

@@ -4,9 +4,9 @@ title: Security
## Reporting a Vulnerability
NextAuth.js practices responsible disclosure.
Auth.js practices responsible disclosure.
We request that you contact us directly to report serious issues that might impact the security of sites using NextAuth.js.
We request that you contact us directly to report serious issues that might impact the security of sites using Auth.js.
If you contact us regarding a serious issue:

View File

@@ -2,7 +2,7 @@
title: Upgrade Guide (v4)
---
NextAuth.js version 4 includes a few breaking changes from the last major version (3.x). So we're here to help you upgrade your applications as smoothly as possible. It should be possible to upgrade from any version of 3.x to the latest 4 release by following the next few migration steps.
Auth.js version 4 includes a few breaking changes from the last major version (3.x). So we're here to help you upgrade your applications as smoothly as possible. It should be possible to upgrade from any version of 3.x to the latest 4 release by following the next few migration steps.
:::note
Version 4 has been released to GA 🚨
@@ -222,7 +222,7 @@ export default NextAuth({
The logger API has been simplified to use at most two parameters, where the second is usually an object (`metadata`) containing an `error` object. If you are not using the logger settings you can ignore this change.
```diff
// [...nextauth.js]
// [...Auth.js]
import log from "some-logger-service"
...
logger: {
@@ -288,7 +288,7 @@ Most importantly, the core `next-auth` package no longer ships with `typeorm` or
You can find the official Adapters in the `packages` directory in the primary monorepo ([nextauthjs/next-auth](https://github.com/nextauthjs/next-auth)). Although you can still [create your own](/guides/adapters/creating-a-database-adapter) with a new, [simplified Adapter API](https://github.com/nextauthjs/next-auth/pull/2361).
If you have a database that was created with a `3.x.x` or earlier version of NextAuth.js, you will need to run a migration to update the schema to the new version 4 database model. See the bottom of this migration guide for database specific migration examples.
If you have a database that was created with a `3.x.x` or earlier version of Auth.js, you will need to run a migration to update the schema to the new version 4 database model. See the bottom of this migration guide for database specific migration examples.
1. If you use the built-in TypeORM or Prisma adapters, these have been removed from the core `next-auth` package. Thankfully the migration is easy; you just need to install the external packages for your database and change the import in your `[...nextauth].js`.
@@ -408,7 +408,7 @@ For more info, see the [Models page](/reference/adapters/models).
### Database migration
NextAuth.js v4 has a slightly different database schema compared to v3. If you're using any of our adapters and want to upgrade, you can use on of the below schemas.
Auth.js v4 has a slightly different database schema compared to v3. If you're using any of our adapters and want to upgrade, you can use on of the below schemas.
They are designed to be run directly against the database itself. So instead of having one in Prisma syntax, one in TypeORM syntax, etc. we've decided to just make one for each underlying database type. i.e. one for Postgres, one for MySQL, one for MongoDB, etc.
@@ -424,7 +424,7 @@ RENAME COLUMN "provider_id" "provider"
RENAME COLUMN "provider_account_id" "providerAccountId"
DROP COLUMN "provider_type"
DROP COLUMN "compound_id"
/* The following two timestamp columns have never been necessary for NextAuth.js to function, but can be kept if you want */
/* The following two timestamp columns have never been necessary for Auth.js to function, but can be kept if you want */
DROP COLUMN "created_at"
DROP COLUMN "updated_at"
@@ -440,7 +440,7 @@ ADD COLUMN "oauth_token" varchar(255) NULL
/* USER */
ALTER TABLE users
RENAME COLUMN "email_verified" "emailVerified"
/* The following two timestamp columns have never been necessary for NextAuth.js to function, but can be kept if you want */
/* The following two timestamp columns have never been necessary for Auth.js to function, but can be kept if you want */
DROP COLUMN "created_at"
DROP COLUMN "updated_at"
@@ -450,7 +450,7 @@ RENAME COLUMN "session_token" "sessionToken"
CHANGE "user_id" "userId" varchar(255)
ADD CONSTRAINT fk_user_id FOREIGN KEY (userId) REFERENCES users(id)
DROP COLUMN "access_token"
/* The following two timestamp columns have never been necessary for NextAuth.js to function, but can be kept if you want */
/* The following two timestamp columns have never been necessary for Auth.js to function, but can be kept if you want */
DROP COLUMN "created_at"
DROP COLUMN "updated_at"
@@ -458,7 +458,7 @@ DROP COLUMN "updated_at"
ALTER TABLE verification_requests RENAME verification_tokens
ALTER TABLE verification_tokens
DROP COLUMN id
/* The following two timestamp columns have never been necessary for NextAuth.js to function, but can be kept if you want */
/* The following two timestamp columns have never been necessary for Auth.js to function, but can be kept if you want */
DROP COLUMN "created_at"
DROP COLUMN "updated_at"
```
@@ -486,7 +486,7 @@ ALTER TABLE accounts ALTER COLUMN "providerAccountId" TYPE TEXT;
ALTER TABLE accounts ADD CONSTRAINT fk_user_id FOREIGN KEY ("userId") REFERENCES users(id);
ALTER TABLE accounts
DROP COLUMN IF EXISTS "compound_id";
/* The following two timestamp columns have never been necessary for NextAuth.js to function, but can be kept if you want */
/* The following two timestamp columns have never been necessary for Auth.js to function, but can be kept if you want */
ALTER TABLE accounts
DROP COLUMN IF EXISTS "created_at",
DROP COLUMN IF EXISTS "updated_at";
@@ -511,7 +511,7 @@ ALTER TABLE users ALTER COLUMN "email" TYPE TEXT;
ALTER TABLE users ALTER COLUMN "image" TYPE TEXT;
/* Do conversion of TIMESTAMPTZ to BIGINT and then TEXT */
ALTER TABLE users ALTER COLUMN "emailVerified" TYPE TEXT USING CAST(CAST(extract(epoch FROM "emailVerified") AS BIGINT)*1000 AS TEXT);
/* The following two timestamp columns have never been necessary for NextAuth.js to function, but can be kept if you want */
/* The following two timestamp columns have never been necessary for Auth.js to function, but can be kept if you want */
ALTER TABLE users
DROP COLUMN IF EXISTS "created_at",
DROP COLUMN IF EXISTS "updated_at";
@@ -528,7 +528,7 @@ ALTER TABLE sessions ADD CONSTRAINT fk_user_id FOREIGN KEY ("userId") REFERENCES
/* Do conversion of TIMESTAMPTZ to BIGINT and then TEXT */
ALTER TABLE sessions ALTER COLUMN "expires" TYPE TEXT USING CAST(CAST(extract(epoch FROM "expires") AS BIGINT)*1000 AS TEXT);
ALTER TABLE sessions DROP COLUMN IF EXISTS "access_token";
/* The following two timestamp columns have never been necessary for NextAuth.js to function, but can be kept if you want */
/* The following two timestamp columns have never been necessary for Auth.js to function, but can be kept if you want */
ALTER TABLE sessions
DROP COLUMN IF EXISTS "created_at",
DROP COLUMN IF EXISTS "updated_at";
@@ -541,7 +541,7 @@ ALTER TABLE verification_tokens ALTER COLUMN "identifier" TYPE TEXT;
ALTER TABLE verification_tokens ALTER COLUMN "token" TYPE TEXT;
/* Do conversion of TIMESTAMPTZ to BIGINT and then TEXT */
ALTER TABLE verification_tokens ALTER COLUMN "expires" TYPE TEXT USING CAST(CAST(extract(epoch FROM "expires") AS BIGINT)*1000 AS TEXT);
/* The following two timestamp columns have never been necessary for NextAuth.js to function, but can be kept if you want */
/* The following two timestamp columns have never been necessary for Auth.js to function, but can be kept if you want */
ALTER TABLE verification_tokens
DROP COLUMN IF EXISTS "created_at",
DROP COLUMN IF EXISTS "updated_at";
@@ -575,7 +575,7 @@ db.getCollection('sessions').updateMany({}, {
## Missing `secret`
NextAuth.js used to generate a secret for convenience, when the user did not define one. This might have been useful in development, but can be a concern in production. We have always been clear about that in the docs, but from now on, if you forget to define a `secret` property in production, we will show the user an error page. Read more about this option [here](/reference/configuration/auth-config#secret)
Auth.js used to generate a secret for convenience, when the user did not define one. This might have been useful in development, but can be a concern in production. We have always been clear about that in the docs, but from now on, if you forget to define a `secret` property in production, we will show the user an error page. Read more about this option [here](/reference/configuration/auth-config#secret)
You can generate a secret to be placed in the `secret` configuration option via the following command:
@@ -583,7 +583,7 @@ You can generate a secret to be placed in the `secret` configuration option via
$ openssl rand -base64 32
```
Therefore, your NextAuth.js config should look something like this:
Therefore, your Auth.js config should look something like this:
```javascript title="/pages/api/auth/[...nextauth].js"
...

View File

@@ -60,9 +60,9 @@ callbacks: {
* When using the **Credentials Provider** the `user` object is the response returned from the `authorize` callback and the `profile` object is the raw body of the `HTTP POST` submission.
:::note
When using NextAuth.js with a database, the User object will be either a user object from the database (including the User ID) if the user has signed in before or a simpler prototype user object (i.e. name, email, image) for users who have not signed in before.
When using Auth.js with a database, the User object will be either a user object from the database (including the User ID) if the user has signed in before or a simpler prototype user object (i.e. name, email, image) for users who have not signed in before.
When using NextAuth.js without a database, the user object will always be a prototype user object, with information extracted from the profile.
When using Auth.js without a database, the user object will always be a prototype user object, with information extracted from the profile.
:::
:::note

View File

@@ -2,17 +2,17 @@
title: Deployment
---
Deploying NextAuth.js only requires a few steps. It can be run anywhere a Next.js application can. Therefore, in a default configuration using only JWT session strategy, i.e. without a database, you will only need these few things in addition to your application:
Deploying Auth.js only requires a few steps. It can be run anywhere a Next.js application can. Therefore, in a default configuration using only JWT session strategy, i.e. without a database, you will only need these few things in addition to your application:
1. NextAuth.js environment variables
1. Auth.js environment variables
- `NEXTAUTH_SECRET`
- `NEXTAUTH_URL`
2. NextAuth.js API Route and its configuration (`/pages/api/auth/[...nextauth].js`).
2. Auth.js API Route and its configuration (`/pages/api/auth/[...nextauth].js`).
- OAuth Provider `clientId` / `clientSecret`
Deploying a modern JavaScript application using NextAuth.js consists of making sure your environment variables are set correctly as well as the configuration in the NextAuth.js API route is setup, as well as any configuration (like Callback URLs, etc.) are correctly done in your OAuth provider(s) themselves.
Deploying a modern JavaScript application using Auth.js consists of making sure your environment variables are set correctly as well as the configuration in the Auth.js API route is setup, as well as any configuration (like Callback URLs, etc.) are correctly done in your OAuth provider(s) themselves.
See below for more detailed provider settings.
@@ -31,7 +31,7 @@ A few notes about deploying to Vercel. The environment variables are read server
### Securing a preview deployment
Securing a preview deployment (with an OAuth provider) comes with some critical obstacles. Most OAuth providers only allow a single redirect/callback URL, or at least a set of full static URLs. Meaning you cannot set the value before publishing the site and you cannot use wildcard subdomains in the callback URL settings of your OAuth provider. Here are a few ways you can still use NextAuth.js to secure your Preview Deployments.
Securing a preview deployment (with an OAuth provider) comes with some critical obstacles. Most OAuth providers only allow a single redirect/callback URL, or at least a set of full static URLs. Meaning you cannot set the value before publishing the site and you cannot use wildcard subdomains in the callback URL settings of your OAuth provider. Here are a few ways you can still use Auth.js to secure your Preview Deployments.
#### Using the Credentials Provider
@@ -87,7 +87,7 @@ Preview deployments at Vercel are often available via multiple URLs. For example
Netlify is very similar to Vercel in that you can deploy a Next.js project without almost any extra work.
In order to setup NextAuth.js correctly here, you will want to make sure you add your `NEXTAUTH_SECRET` environment variable in the project settings. If you are using the [Essential Next.js Build Plugin](https://github.com/netlify/netlify-plugin-nextjs) within your project, you **do not** need to set the `NEXTAUTH_URL` environment variable as it is set automatically as part of the build process.
In order to setup Auth.js correctly here, you will want to make sure you add your `NEXTAUTH_SECRET` environment variable in the project settings. If you are using the [Essential Next.js Build Plugin](https://github.com/netlify/netlify-plugin-nextjs) within your project, you **do not** need to set the `NEXTAUTH_URL` environment variable as it is set automatically as part of the build process.
Netlify also exposes some [system environment variables](https://docs.netlify.com/configure-builds/environment-variables/) from which you can check which `NODE_ENV` you are currently in and much more.

View File

@@ -4,13 +4,13 @@ title: Custom Initialization
In Next.js, you can define an API route that will catch all requests that begin with a certain path. Conveniently, this is called [Catch all API routes](https://nextjs.org/docs/api-routes/dynamic-api-routes#catch-all-api-routes).
When you define a `/pages/api/auth/[...nextauth]` JS/TS file, you instruct NextAuth.js that every API request beginning with `/api/auth/*` should be handled by the code written in the `[...nextauth]` file.
When you define a `/pages/api/auth/[...nextauth]` JS/TS file, you instruct Auth.js that every API request beginning with `/api/auth/*` should be handled by the code written in the `[...nextauth]` file.
Depending on your use case, you can initialize NextAuth.js in two different ways:
Depending on your use case, you can initialize Auth.js in two different ways:
## Simple initialization
In most cases, you won't need to worry about what `NextAuth.js` does, and you will get by just fine with the following initialization:
In most cases, you won't need to worry about what `Auth.js` does, and you will get by just fine with the following initialization:
```ts title="/pages/api/auth/[...nextauth].js"
import NextAuth from "next-auth"
@@ -26,9 +26,9 @@ This is the preferred initialization in tutorials/other parts of the documentati
## Advanced initialization
If you have a specific use case and need to make NextAuth.js do something slightly different than what it is designed for, keep in mind, the `[...nextauth].js` config file is still just **a regular [API Route](https://nextjs.org/docs/api-routes/introduction)** at the end of the day.
If you have a specific use case and need to make Auth.js do something slightly different than what it is designed for, keep in mind, the `[...nextauth].js` config file is still just **a regular [API Route](https://nextjs.org/docs/api-routes/introduction)** at the end of the day.
That said, you can initialize NextAuth.js like this:
That said, you can initialize Auth.js like this:
```ts title="/pages/api/auth/[...nextauth].ts"
import type { NextApiRequest, NextApiResponse } from "next"
@@ -47,7 +47,7 @@ The `...` section will still be your [options](/reference/configuration/auth-con
You could for example log the request, add headers, read `query` or `body` parameters, whatever you would do in an API route.
:::tip
Since this is a catch-all route, remember to check what kind of NextAuth.js "action" is running. Compare the REST API with the `req.query.nextauth` parameter.
Since this is a catch-all route, remember to check what kind of Auth.js "action" is running. Compare the REST API with the `req.query.nextauth` parameter.
For example to execute something on the "callback" action when the request is a POST method, you can check for `req.query.nextauth.includes("callback") && req.method === "POST"`
:::

View File

@@ -7,7 +7,7 @@ sidebar_label: Custom JWT encoding
If you use middleware to protect routes, make sure the same method is also set in the [`_middleware.ts` options](/reference/nextjs/#custom-jwt-decode-method)
:::
NextAuth.js uses encrypted JSON Web Tokens ([JWE](https://datatracker.ietf.org/doc/html/rfc7516)) by default. Unless you have a good reason, we recommend keeping this behaviour. Although you can override this using the `encode` and `decode` methods. Both methods must be defined at the same time.
Auth.js uses encrypted JSON Web Tokens ([JWE](https://datatracker.ietf.org/doc/html/rfc7516)) by default. Unless you have a good reason, we recommend keeping this behaviour. Although you can override this using the `encode` and `decode` methods. Both methods must be defined at the same time.
```js
jwt: {

View File

@@ -2,9 +2,9 @@
title: Pages
---
NextAuth.js automatically creates simple, unbranded authentication pages for handling Sign in, Sign out, Email Verification and displaying error messages.
Auth.js automatically creates simple, unbranded authentication pages for handling Sign in, Sign out, Email Verification and displaying error messages.
The options displayed on the sign-up page are automatically generated based on the providers specified in the options passed to NextAuth.js.
The options displayed on the sign-up page are automatically generated based on the providers specified in the options passed to Auth.js.
To add a custom login page, you can use the `pages` option:

View File

@@ -2,7 +2,7 @@
title: Refresh token rotation
---
While NextAuth.js doesn't automatically handle access token rotation for [OAuth providers](/reference/providers/oauth-builtin) yet, this functionality can be implemented using [callbacks](/guides/basics/callbacks).
While Auth.js doesn't automatically handle access token rotation for [OAuth providers](/reference/providers/oauth-builtin) yet, this functionality can be implemented using [callbacks](/guides/basics/callbacks).
## Source Code

View File

@@ -2,7 +2,7 @@
title: Securing Pages & API routes
---
You can easily protect client and server side rendered pages and API routes with NextAuth.js.
You can easily protect client and server side rendered pages and API routes with Auth.js.
_You can find working examples of the approaches shown below in the [example project](https://github.com/nextauthjs/next-auth-example/)._
@@ -41,7 +41,7 @@ export default function Page() {
### Next.js (Middleware)
With NextAuth.js 4.2.0 and Next.js 12, you can now protect your pages via the middleware pattern more easily. If you would like to protect all pages, you can create a `_middleware.js` file in your root `pages` directory which looks like this.
With Auth.js 4.2.0 and Next.js 12, you can now protect your pages via the middleware pattern more easily. If you would like to protect all pages, you can create a `_middleware.js` file in your root `pages` directory which looks like this.
```js title="/middleware.js"
export { default } from "next-auth/middleware"

View File

@@ -77,7 +77,7 @@ The credentials provider can also be used to integrate with a service like [Sign
For more information, check out the links below:
- [Tutorial](https://docs.login.xyz/integrations/nextauth.js)
- [Tutorial](https://docs.login.xyz/integrations/Auth.js)
- [Example App Repo](https://github.com/spruceid/siwe-next-auth-example).
- [Example App Demo](https://siwe-next-auth-example2.vercel.app/).

View File

@@ -29,7 +29,7 @@ You can override any of the options to suit your own use case.
## Configuration
1. NextAuth.js does not include `nodemailer` as a dependency, so you'll need to install it yourself if you want to use the Email Provider. Run `npm install nodemailer` or `yarn add nodemailer`.
1. Auth.js does not include `nodemailer` as a dependency, so you'll need to install it yourself if you want to use the Email Provider. Run `npm install nodemailer` or `yarn add nodemailer`.
2. You will need an SMTP account; ideally for one of the [services known to work with `nodemailer`](https://community.nodemailer.com/2-0-0-beta/setup-smtp/well-known-services/).
3. There are two ways to configure the SMTP server connection.

View File

@@ -2,4 +2,4 @@
"label": "Providers",
"collapsible": true,
"collapsed": true
}
}

View File

@@ -2,4 +2,4 @@
"label": "Adapters",
"collapsible": true,
"collapsed": true
}
}

View File

@@ -2,7 +2,7 @@
title: Using a database adapter
---
An **Adapter** in NextAuth.js connects your application to whatever database or backend system you want to use to store data for users, their accounts, sessions, etc. Adapters are optional, unless you need to persist user information in your own database, or you want to implement certain flows. The [Email Provider](/getting-started/email-tutorial) requires an adapter to be able to save [Verification Tokens](/reference/adapters/models#verification-token).
An **Adapter** in Auth.js connects your application to whatever database or backend system you want to use to store data for users, their accounts, sessions, etc. Adapters are optional, unless you need to persist user information in your own database, or you want to implement certain flows. The [Email Provider](/getting-started/email-tutorial) requires an adapter to be able to save [Verification Tokens](/reference/adapters/models#verification-token).
:::tip
When using a database, you can still use JWT for session handling for fast access. See the [`session.strategy`](/reference/configuration/auth-config#session) option. Read about the trade-offs of JWT in the [FAQ](/concepts/faq#json-web-tokens).

View File

@@ -2,4 +2,4 @@
"label": "Testing",
"collapsible": true,
"collapsed": true
}
}

View File

@@ -2,7 +2,7 @@
title: Testing with Cypress
---
To test an implementation of NextAuth.js, we encourage you to use [Cypress](https://cypress.io).
To test an implementation of Auth.js, we encourage you to use [Cypress](https://cypress.io).
## Setting up Cypress
@@ -42,7 +42,7 @@ Second, a cypress file for environment variables. These can be defined in `cypre
}
```
You must change the login credentials you want to use, but you can also redefine the name of the `GOOGLE_*` variables if you're using a different provider. `COOKIE_NAME`, however, must be set to that value for NextAuth.js.
You must change the login credentials you want to use, but you can also redefine the name of the `GOOGLE_*` variables if you're using a different provider. `COOKIE_NAME`, however, must be set to that value for Auth.js.
Third, if you're using the `cypress-social-login` plugin, you must add this to your `/cypress/plugins/index.js` file like so:
@@ -65,7 +65,7 @@ Finally, you can also add the following npm scripts to your `package.json`:
## Writing a test
Once we've got all that configuration out of the way, we can begin writing tests to login using NextAuth.js.
Once we've got all that configuration out of the way, we can begin writing tests to login using Auth.js.
The basic login test looks like this:

View File

@@ -2,4 +2,4 @@
"label": "Corporate proxies",
"collapsible": true,
"collapsed": true
}
}

View File

@@ -4,7 +4,7 @@ title: Corporate email sign up
If you use Office 365 or Outlook, or potentially other Email systems, you may notice your Email invitation Links not working.
This is because the invitation Email your User is receiving is being scanned by the Email provider. In the specific case of Outlook and their "SafeLink" feature, they send a HEAD request to each link in the Email. This request will trigger the NextAuth.js catch-all API Route with the users invitation token, in effect using it up.
This is because the invitation Email your User is receiving is being scanned by the Email provider. In the specific case of Outlook and their "SafeLink" feature, they send a HEAD request to each link in the Email. This request will trigger the Auth.js catch-all API Route with the users invitation token, in effect using it up.
Therefore, when the user wants to use it themselves, and clicks on the invitation link they will be greeted with an error message that the invitation is invalid.
@@ -14,7 +14,7 @@ Therefore, when the user wants to use it themselves, and clicks on the invitatio
The first potential workaround is to simply disable this "SafeLink" feature for your organisation. Microsoft has more details on this [here](https://docs.microsoft.com/en-us/microsoft-365/security/office-365-security/safe-links?view=o365-worldwide#do-not-rewrite-the-following-urls-lists-in-safe-links-policies). Obviously this won't be an option for everyone as this is usually a part of corporate IT policy.
### Update NextAuth.js for 'HEAD' requests
### Update Auth.js for 'HEAD' requests
The second option is to modify your `[...nextauth].js` catch-all API route a bit to gracefully handle these initial `HEAD` requests from the email service, without accidentally using up the invitation link.
@@ -36,4 +36,4 @@ export default async function auth(req: NextApiRequest, res: NextApiResponse) {
}
```
This should allow you to successfully use NextAuth.js's Email provider behind strict corporate IT settings.
This should allow you to successfully use Auth.js's Email provider behind strict corporate IT settings.

View File

@@ -2,7 +2,7 @@
title: Corporate proxy
---
Using NextAuth.js behind a corporate proxy is not supported out of the box. This is due to the fact that the underlying library we use, [`openid-client`](https://npm.im/openid-client) which uses the built-in Node.js `http` / `https` libraries, and those do not support proxys by default:
Using Auth.js behind a corporate proxy is not supported out of the box. This is due to the fact that the underlying library we use, [`openid-client`](https://npm.im/openid-client) which uses the built-in Node.js `http` / `https` libraries, and those do not support proxys by default:
- [`http` docs](https://nodejs.org/dist/latest-v18.x/docs/api/http.html)
- [`https` docs](https://nodejs.org/dist/latest-v18.x/docs/api/https.html)

View File

@@ -2,4 +2,4 @@
"label": "Other",
"collapsible": true,
"collapsed": true
}
}

View File

@@ -8,9 +8,9 @@ title: Community resources
## Basics
#### [Introduction to NextAuth.js](https://www.youtube.com/watch?v=npZsJxWntJM) <svg role="img" viewBox="0 0 24 24" height="24" width="24" style={{ marginLeft: '5px', marginBottom:'-6px'}} xmlns="http://www.w3.org/2000/svg"><title>YouTube</title><path fill="#ff0000" d="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z"/></svg>
#### [Introduction to Auth.js](https://www.youtube.com/watch?v=npZsJxWntJM) <svg role="img" viewBox="0 0 24 24" height="24" width="24" style={{ marginLeft: '5px', marginBottom:'-6px'}} xmlns="http://www.w3.org/2000/svg"><title>YouTube</title><path fill="#ff0000" d="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z"/></svg>
- This is an introductory video to NextAuth.js for beginners. In this video, it is explained how to set up authentication in a few easy steps and add different configurations to make it more robust and secure.
- This is an introductory video to Auth.js for beginners. In this video, it is explained how to set up authentication in a few easy steps and add different configurations to make it more robust and secure.
#### [Authentication patterns for Next.js](https://nextjs.org/docs/authentication) <svg xmlns="http://www.w3.org/2000/svg" style={{ marginLeft: '5px', marginBottom:'-6px'}} height="20" width="20" fill="none" viewBox="0 0 24 24" stroke="currentColor"><title>External</title><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" /> </svg>
@@ -18,45 +18,45 @@ title: Community resources
#### [Adding Authentication to an existing Next.js Application in no time!](https://dev.to/ndom91/adding-authentication-to-an-existing-serverless-next-js-app-in-no-time-with-nextauth-js-192h) <svg style={{ marginLeft: '5px', marginBottom:'-6px'}} width="30" height="25" viewBox="0 0 50 40" fill="none" xmlns="http://www.w3.org/2000/svg"><rect width="50" height="40" rx="3" style={{ fill: '#000' }}></rect><path d="M19.099 23.508c0 1.31-.423 2.388-1.27 3.234-.838.839-1.942 1.258-3.312 1.258h-4.403V12.277h4.492c1.31 0 2.385.423 3.224 1.27.846.838 1.269 1.912 1.269 3.223v6.738zm-2.808 0V16.77c0-.562-.187-.981-.562-1.258-.374-.285-.748-.427-1.122-.427h-1.685v10.107h1.684c.375 0 .75-.138 1.123-.415.375-.285.562-.708.562-1.27zM28.185 28h-5.896c-.562 0-1.03-.187-1.404-.561-.375-.375-.562-.843-.562-1.404V14.243c0-.562.187-1.03.562-1.404.374-.375.842-.562 1.404-.562h5.896v2.808H23.13v3.65h3.088v2.808h-3.088v3.65h5.054V28zm7.12 0c-.936 0-1.684-.655-2.246-1.965l-3.65-13.758h3.089l2.807 10.804 2.808-10.804H41.2l-3.65 13.758C36.99 27.345 36.241 28 35.305 28z" style={{ fill: '#fff' }}></path></svg>
- This tutorial walks one through adding NextAuth.js to an existing project. Including setting up the OAuth client id and secret, adding the API routes for authentication, protecting pages and API routes behind that authentication, etc.
- This tutorial walks one through adding Auth.js to an existing project. Including setting up the OAuth client id and secret, adding the API routes for authentication, protecting pages and API routes behind that authentication, etc.
#### [Adding social authentication support to a Next.js app](https://getstarted.sh/bulletproof-next/add-social-authentication) <svg xmlns="http://www.w3.org/2000/svg" style={{ marginLeft: '5px', marginBottom:'-6px'}} height="20" width="20" fill="none" viewBox="0 0 24 24" stroke="currentColor"><title>External</title> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" /> </svg>
- A tutorial by Arunoda Susirpiala. Checkout [GetStarted](https://getstarted.sh/) for more examples.
#### [How to Authenticate Next.js Apps with Twitter & NextAuth.js](https://spacejelly.dev/posts/how-to-authenticate-next-js-apps-with-twitter-nextauth-js/) <svg xmlns="http://www.w3.org/2000/svg" style={{ marginLeft: '5px', marginBottom:'-6px'}} height="20" width="20" fill="none" viewBox="0 0 24 24" stroke="currentColor"><title>External</title> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" /> </svg>
#### [How to Authenticate Next.js Apps with Twitter & Auth.js](https://spacejelly.dev/posts/how-to-authenticate-next-js-apps-with-twitter-nextauth-js/) <svg xmlns="http://www.w3.org/2000/svg" style={{ marginLeft: '5px', marginBottom:'-6px'}} height="20" width="20" fill="none" viewBox="0 0 24 24" stroke="currentColor"><title>External</title> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" /> </svg>
- Learn how to add Twitter authentication and login to a Next.js app both client-side and server-side with NextAuth.js.
- Learn how to add Twitter authentication and login to a Next.js app both client-side and server-side with Auth.js.
#### [NextJS Authentication Crash Course with NextAuth.js](https://youtu.be/o_wZIVmWteQ) <svg role="img" viewBox="0 0 24 24" height="24" width="24" style={{ marginLeft: '5px', marginBottom:'-6px'}} xmlns="http://www.w3.org/2000/svg"><title>YouTube</title><path fill="#ff0000" d="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z"/></svg>
#### [NextJS Authentication Crash Course with Auth.js](https://youtu.be/o_wZIVmWteQ) <svg role="img" viewBox="0 0 24 24" height="24" width="24" style={{ marginLeft: '5px', marginBottom:'-6px'}} xmlns="http://www.w3.org/2000/svg"><title>YouTube</title><path fill="#ff0000" d="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z"/></svg>
- This tutorial dives into the ins and outs of NextAuth, including using the Email, Github, Twitter and Auth0 providers in under an hour.
#### [Create your own NextAuth.js Login Pages](https://youtu.be/kB6YNYZ63fw) <svg role="img" viewBox="0 0 24 24" height="24" width="24" style={{ marginLeft: '5px', marginBottom:'-6px'}} xmlns="http://www.w3.org/2000/svg"><title>YouTube</title><path fill="#ff0000" d="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z"/></svg>
#### [Create your own Auth.js Login Pages](https://youtu.be/kB6YNYZ63fw) <svg role="img" viewBox="0 0 24 24" height="24" width="24" style={{ marginLeft: '5px', marginBottom:'-6px'}} xmlns="http://www.w3.org/2000/svg"><title>YouTube</title><path fill="#ff0000" d="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z"/></svg>
- This tutorial shows you how to jump in and create your own custom login pages versus using the ones provided by NextAuth.js
- This tutorial shows you how to jump in and create your own custom login pages versus using the ones provided by Auth.js
#### [Passwordless Authentication with next-auth](https://www.youtube.com/watch?v=GPBD3acOx_M) <svg role="img" viewBox="0 0 24 24" height="24" width="24" style={{ marginLeft: '5px', marginBottom:'-6px'}} xmlns="http://www.w3.org/2000/svg"><title>YouTube</title><path fill="#ff0000" d="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z"/></svg>
- A video tutorial by Xiaoru Li from Prisma.
#### [How to authenticate Next.js Apps with Sign-In With Ethereum (SIWE) & NextAuth.js](https://docs.login.xyz/integrations/nextauth.js) <svg xmlns="http://www.w3.org/2000/svg" style={{ marginLeft: '5px', marginBottom:'-6px'}} height="20" width="20" fill="none" viewBox="0 0 24 24" stroke="currentColor"><title>External</title> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" /> </svg>
#### [How to authenticate Next.js Apps with Sign-In With Ethereum (SIWE) & Auth.js](https://docs.login.xyz/integrations/Auth.js) <svg xmlns="http://www.w3.org/2000/svg" style={{ marginLeft: '5px', marginBottom:'-6px'}} height="20" width="20" fill="none" viewBox="0 0 24 24" stroke="currentColor"><title>External</title> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" /> </svg>
- Learn how to use Sign-In With Ethereum to authenticate your users with their existing Ethereum wallets - identifiers they personally control.
- Example application: [spruceid/siwe-next-auth-example](https://github.com/spruceid/siwe-next-auth-example)
#### [Next.js Authentication with Okta and NextAuth.js 4.0](https://thetombomb.com/posts/nextjs-nextauth-okta) <svg xmlns="http://www.w3.org/2000/svg" style={{ marginLeft: '5px', marginBottom:'-6px'}} height="20" width="20" fill="none" viewBox="0 0 24 24" stroke="currentColor"><title>External</title> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" /> </svg>
#### [Next.js Authentication with Okta and Auth.js 4.0](https://thetombomb.com/posts/nextjs-nextauth-okta) <svg xmlns="http://www.w3.org/2000/svg" style={{ marginLeft: '5px', marginBottom:'-6px'}} height="20" width="20" fill="none" viewBox="0 0 24 24" stroke="currentColor"><title>External</title> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" /> </svg>
- Learn how to perform authentication with an OIDC Application in Okta and NextAuth.js.
- Learn how to perform authentication with an OIDC Application in Okta and Auth.js.
## Fullstack
#### [Build a FullStack App with Next.js, NextAuth.js, Supabase & Prisma](https://themodern.dev/courses/build-a-fullstack-app-with-nextjs-supabase-and-prisma-322389284337222224) <svg xmlns="http://www.w3.org/2000/svg" style={{ marginLeft: '5px', marginBottom:'-6px'}} height="20" width="20" fill="none" viewBox="0 0 24 24" stroke="currentColor"><title>External</title> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" /> </svg>
#### [Build a FullStack App with Next.js, Auth.js, Supabase & Prisma](https://themodern.dev/courses/build-a-fullstack-app-with-nextjs-supabase-and-prisma-322389284337222224) <svg xmlns="http://www.w3.org/2000/svg" style={{ marginLeft: '5px', marginBottom:'-6px'}} height="20" width="20" fill="none" viewBox="0 0 24 24" stroke="currentColor"><title>External</title> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" /> </svg>
In this [free course](https://themodern.dev/courses/build-a-fullstack-app-with-nextjs-supabase-and-prisma-322389284337222224), you'll learn how to build a full-stack app using the following technologies:
- **Next.js** - The React framework for building the UI of the app and the REST API
- **NextAuth.js** - For implementing passwordless and OAuth authentication
- **Auth.js** - For implementing passwordless and OAuth authentication
- **Supabase** - For persisting the app data into a PostgreSQL database and storing media files
- **Prisma** - For making it easy to read and write data from our app from and to the database
@@ -74,7 +74,7 @@ Learn how to implement passwordless/magic link authentication with database stor
This tutorial covers:
- Configuring Next.js, NextAuth.js, and Fauna to work together seamlessly
- Configuring Next.js, Auth.js, and Fauna to work together seamlessly
- Using Next.js dynamic API routes to handle authentication requests
- Using Fauna and the Fauna Adapter for `next-auth` to persist users, email sign in tokens, and sessions
- Creating custom login and confirmation pages with React + Tailwind CSS
@@ -84,9 +84,9 @@ This tutorial covers:
- In this post, you'll learn how to add passwordless authentication to your Next.js app using Prisma and next-auth. By the end of this tutorial, your users will be able to log in to your app with either their GitHub account or a Slack-styled magic link sent right to their Email inbox. By Xiaoru Li.
#### [Fullstack Authentication Example with Next.js and NextAuth.js](https://github.com/prisma/prisma-examples/tree/latest/typescript/rest-nextjs-api-routes-auth) <svg xmlns="http://www.w3.org/2000/svg" style={{ marginLeft: '5px', marginBottom:'-6px'}} height="20" width="20" fill="none" viewBox="0 0 24 24" stroke="currentColor"><title>External</title> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" /> </svg>
#### [Fullstack Authentication Example with Next.js and Auth.js](https://github.com/prisma/prisma-examples/tree/latest/typescript/rest-nextjs-api-routes-auth) <svg xmlns="http://www.w3.org/2000/svg" style={{ marginLeft: '5px', marginBottom:'-6px'}} height="20" width="20" fill="none" viewBox="0 0 24 24" stroke="currentColor"><title>External</title> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" /> </svg>
- This example shows how to implement a full-stack app in TypeScript with Next.js using Prisma Client as a backend. It also demonstrates how to implement authentication using NextAuth.js. By Nikolas Burk at Prisma.
- This example shows how to implement a full-stack app in TypeScript with Next.js using Prisma Client as a backend. It also demonstrates how to implement authentication using Auth.js. By Nikolas Burk at Prisma.
## Advanced
@@ -96,23 +96,23 @@ This tutorial covers:
#### [How to Configure Azure AD B2C Authentication with Next.js](https://benjaminwfox.com/blog/tech/how-to-configure-azure-b2c-with-nextjs) <svg xmlns="http://www.w3.org/2000/svg" style={{ marginLeft: '5px', marginBottom:'-6px'}} height="20" width="20" fill="none" viewBox="0 0 24 24" stroke="currentColor"><title>External</title> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" /> </svg>
- Configuring authentication with Azure B2C in Next.js is not a particularly straight forward process. We'll look at how to facilitate this using the NextAuth.js library. By Ben Fox.
- Configuring authentication with Azure B2C in Next.js is not a particularly straight forward process. We'll look at how to facilitate this using the Auth.js library. By Ben Fox.
#### [Sign in with Apple in NextJS](https://thesiddd.com/blog/apple-auth) <svg xmlns="http://www.w3.org/2000/svg" style={{ marginLeft: '5px', marginBottom:'-6px'}} height="20" width="20" fill="none" viewBox="0 0 24 24" stroke="currentColor"><title>External</title> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" /> </svg>
- This tutorial walks step by step on how to get sign in with Apple working (both locally and on a deployed website) using NextAuth.js.
- This tutorial walks step by step on how to get sign in with Apple working (both locally and on a deployed website) using Auth.js.
#### [Using NextAuth.js with Magic links](https://dev.to/narciero/using-nextauth-js-with-magic-links-df4) <svg style={{ marginLeft: '5px', marginBottom:'-6px'}} width="30" height="25" viewBox="0 0 50 40" fill="none" xmlns="http://www.w3.org/2000/svg"><rect width="50" height="40" rx="3" style={{ fill: '#000' }}></rect><path d="M19.099 23.508c0 1.31-.423 2.388-1.27 3.234-.838.839-1.942 1.258-3.312 1.258h-4.403V12.277h4.492c1.31 0 2.385.423 3.224 1.27.846.838 1.269 1.912 1.269 3.223v6.738zm-2.808 0V16.77c0-.562-.187-.981-.562-1.258-.374-.285-.748-.427-1.122-.427h-1.685v10.107h1.684c.375 0 .75-.138 1.123-.415.375-.285.562-.708.562-1.27zM28.185 28h-5.896c-.562 0-1.03-.187-1.404-.561-.375-.375-.562-.843-.562-1.404V14.243c0-.562.187-1.03.562-1.404.374-.375.842-.562 1.404-.562h5.896v2.808H23.13v3.65h3.088v2.808h-3.088v3.65h5.054V28zm7.12 0c-.936 0-1.684-.655-2.246-1.965l-3.65-13.758h3.089l2.807 10.804 2.808-10.804H41.2l-3.65 13.758C36.99 27.345 36.241 28 35.305 28z" style={{ fill: '#fff' }}></path></svg>
#### [Using Auth.js with Magic links](https://dev.to/narciero/using-nextauth-js-with-magic-links-df4) <svg style={{ marginLeft: '5px', marginBottom:'-6px'}} width="30" height="25" viewBox="0 0 50 40" fill="none" xmlns="http://www.w3.org/2000/svg"><rect width="50" height="40" rx="3" style={{ fill: '#000' }}></rect><path d="M19.099 23.508c0 1.31-.423 2.388-1.27 3.234-.838.839-1.942 1.258-3.312 1.258h-4.403V12.277h4.492c1.31 0 2.385.423 3.224 1.27.846.838 1.269 1.912 1.269 3.223v6.738zm-2.808 0V16.77c0-.562-.187-.981-.562-1.258-.374-.285-.748-.427-1.122-.427h-1.685v10.107h1.684c.375 0 .75-.138 1.123-.415.375-.285.562-.708.562-1.27zM28.185 28h-5.896c-.562 0-1.03-.187-1.404-.561-.375-.375-.562-.843-.562-1.404V14.243c0-.562.187-1.03.562-1.404.374-.375.842-.562 1.404-.562h5.896v2.808H23.13v3.65h3.088v2.808h-3.088v3.65h5.054V28zm7.12 0c-.936 0-1.684-.655-2.246-1.965l-3.65-13.758h3.089l2.807 10.804 2.808-10.804H41.2l-3.65 13.758C36.99 27.345 36.241 28 35.305 28z" style={{ fill: '#fff' }}></path></svg>
- Learn how to use [Magic.Link](https://magic.link) authentication with [NextAuth.js](https://next-auth.js.org) to enable passwordless authentication without a database.
- Learn how to use [Magic.Link](https://magic.link) authentication with [Auth.js](https://next-auth.js.org) to enable passwordless authentication without a database.
## Database
#### [Create a NextAuth.js Custom Adapter with HarperDB & Next.js](https://spacejelly.dev/posts/how-to-create-a-nextauth-js-custom-adapter-with-harperdb-next-js/) <svg xmlns="http://www.w3.org/2000/svg" style={{ marginLeft: '5px', marginBottom:'-6px'}} height="20" width="20" fill="none" viewBox="0 0 24 24" stroke="currentColor"><title>External</title> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" /> </svg>
#### [Create a Auth.js Custom Adapter with HarperDB & Next.js](https://spacejelly.dev/posts/how-to-create-a-nextauth-js-custom-adapter-with-harperdb-next-js/) <svg xmlns="http://www.w3.org/2000/svg" style={{ marginLeft: '5px', marginBottom:'-6px'}} height="20" width="20" fill="none" viewBox="0 0 24 24" stroke="currentColor"><title>External</title> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" /> </svg>
- Use a custom database in a Custom Adapter for persisted NextAuth.js sessions using HarperDB as an example.
- Use a custom database in a Custom Adapter for persisted Auth.js sessions using HarperDB as an example.
- Video tutorial also available: <https://www.youtube.com/watch?v=pu7xBv7sZ8s>
#### [Using NextAuth.js with Prisma and PlanetScale serverless databases](https://github.com/planetscale/nextjs-planetscale-starter) <svg xmlns="http://www.w3.org/2000/svg" style={{ marginLeft: '5px', marginBottom:'-6px'}} height="20" width="20" fill="none" viewBox="0 0 24 24" stroke="currentColor"><title>External</title> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" /> </svg>
#### [Using Auth.js with Prisma and PlanetScale serverless databases](https://github.com/planetscale/nextjs-planetscale-starter) <svg xmlns="http://www.w3.org/2000/svg" style={{ marginLeft: '5px', marginBottom:'-6px'}} height="20" width="20" fill="none" viewBox="0 0 24 24" stroke="currentColor"><title>External</title> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" /> </svg>
- How to set up a PlanetScale database to fetch and store user / account data with the Prisma adapter.

View File

@@ -4,7 +4,7 @@ title: Initialization
## Options
Options are passed to NextAuth.js when initializing it in a server environment like a Next.js API Route.
Options are passed to Auth.js when initializing it in a server environment like a Next.js API Route.
### providers
@@ -94,7 +94,7 @@ JSON Web Tokens can be used for session tokens if enabled with `session: { strat
```js
jwt: {
// The maximum age of the NextAuth.js issued JWT in seconds.
// The maximum age of the Auth.js issued JWT in seconds.
// Defaults to `session.maxAge`.
maxAge: 60 * 60 * 24 * 30,
// You can define your own encode/decode functions for signing and encryption
@@ -266,7 +266,7 @@ events: {
#### Description
By default NextAuth.js does not include an adapter any longer. If you would like to persist user / account data, please install one of the many available adapters. More information can be found in the [adapter documentation](/reference/adapters/overview).
By default Auth.js does not include an adapter any longer. If you would like to persist user / account data, please install one of the many available adapters. More information can be found in the [adapter documentation](/reference/adapters/overview).
---
@@ -354,7 +354,7 @@ Advanced options are passed the same way as basic options, but may have complex
#### Description
When set to `true` (the default for all site URLs that start with `https://`) then all cookies set by NextAuth.js will only be accessible from HTTPS URLs.
When set to `true` (the default for all site URLs that start with `https://`) then all cookies set by Auth.js will only be accessible from HTTPS URLs.
This option defaults to `false` on URLs that start with `http://` (e.g. `http://localhost:3000`) for developer convenience.
@@ -375,9 +375,9 @@ Setting this option to _false_ in production is a security risk and may allow se
#### Description
Cookies in NextAuth.js are chunked by default, meaning that once they reach the 4kb limit, we will create a new cookie with the `.{number}` suffix and reassemble the cookies in the correct order when parsing / reading them. This was introduced to avoid size constraints which can occur when users want to store additional data in their sessionToken, for example.
Cookies in Auth.js are chunked by default, meaning that once they reach the 4kb limit, we will create a new cookie with the `.{number}` suffix and reassemble the cookies in the correct order when parsing / reading them. This was introduced to avoid size constraints which can occur when users want to store additional data in their sessionToken, for example.
You can override the default cookie names and options for any of the cookies used by NextAuth.js.
You can override the default cookie names and options for any of the cookies used by Auth.js.
This is an advanced option and using it is not recommended as you may break authentication or introduce security flaws into your application.

View File

@@ -23,7 +23,7 @@ Using [System Environment Variables](https://vercel.com/docs/concepts/projects/e
## NEXTAUTH_SECRET
Used to encrypt the NextAuth.js JWT, and to hash [email verification tokens](/reference/adapters/models#verification-token). This is the default value for the [`secret`](/reference/configuration/auth-config#secret) option. The `secret` option might be removed in the future in favor of this.
Used to encrypt the Auth.js JWT, and to hash [email verification tokens](/reference/adapters/models#verification-token). This is the default value for the [`secret`](/reference/configuration/auth-config#secret) option. The `secret` option might be removed in the future in favor of this.
If you are using [Middleware](/reference/nextjs/#prerequisites) this environment variable must be set.

View File

@@ -3,7 +3,7 @@ id: client
title: Utilities
---
The NextAuth.js client library makes it easy to interact with sessions from React applications.
The Auth.js client library makes it easy to interact with sessions from React applications.
#### Example Session Object
@@ -33,7 +33,7 @@ The `expires` value is rotated, meaning whenever the session is retrieved from t
- Client Side: **Yes**
- Server Side: **No** (See: [`unstable_getServerSession()`](/reference/nextjs/#unstable_getserversession)
NextAuth.js provides a `getSession()` helper which should be called **client side only** to return the current active session.
Auth.js provides a `getSession()` helper which should be called **client side only** to return the current active session.
On the server side, **this is still available to use**, however, we recommend using `unstable_getServerSession` going forward. The idea behind this is to avoid an additional unnecessary `fetch` call on the server side. For more information, please check out [this issue](https://github.com/nextauthjs/next-auth/issues/1535).
@@ -138,7 +138,7 @@ export default () => <button onClick={() => signIn()}>Sign in</button>
### Starts OAuth sign-in flow when clicked
By default, when calling the `signIn()` method with no arguments, you will be redirected to the NextAuth.js sign-in page. If you want to skip that and get redirected to your provider's page immediately, call the `signIn()` method with the provider's `id`.
By default, when calling the `signIn()` method with no arguments, you will be redirected to the Auth.js sign-in page. If you want to skip that and get redirected to your provider's page immediately, call the `signIn()` method with the provider's `id`.
For example to sign in with Google:

View File

@@ -1,237 +0,0 @@
---
title: React
---
## SessionProvider
Using the supplied `<SessionProvider>` allows instances of `useSession()` to share the session object across components, by using [React Context](https://reactjs.org/docs/context.html) under the hood. It also takes care of keeping the session updated and synced between tabs/windows.
```jsx title="pages/_app.js"
import { SessionProvider } from "next-auth/react"
export default function App({
Component,
pageProps: { session, ...pageProps },
}) {
return (
<SessionProvider session={session}>
<Component {...pageProps} />
</SessionProvider>
)
}
```
If you pass the `session` page prop to the `<SessionProvider>` as in the example above you can avoid checking the session twice on pages that support both server and client side rendering.
This only works on pages where you provide the correct `pageProps`, however. This is normally done in `getInitialProps` or `getServerSideProps` on an individual page basis like so:
```js title="pages/index.js"
import { unstable_getServerSession } from "next-auth/next"
...
export async function getServerSideProps(ctx) {
return {
props: {
session: await unstable_getServerSession(ctx)
}
}
}
```
If every one of your pages needs to be protected, you can do this in `getInitialProps` in `_app`, otherwise you can do it on a page-by-page basis. Alternatively, you can do per page authentication checks client side, instead of having each authentication check be blocking (SSR) by using the method described below in [alternative client session handling](/reference/utilities/#getsession).
### Options
The session state is automatically synchronized across all open tabs/windows and they are all updated whenever they gain or lose focus or the state changes (e.g. a user signs in or out) when `refetchOnWindowFocus` is `true`.
If you have session expiry times of 30 days (the default) or more then you probably don't need to change any of the default options in the Provider. If you need to, you can trigger an update of the session object across all tabs/windows by calling [`getSession()`](/reference/utilities/#getsession) from a client side function.
However, if you need to customize the session behavior and/or are using short session expiry times, you can pass options to the provider to customize the behavior of the `useSession()` hook.
```jsx title="pages/_app.js"
import { SessionProvider } from "next-auth/react"
export default function App({
Component,
pageProps: { session, ...pageProps },
}) {
return (
<SessionProvider
session={session}
// In case you use a custom path and your app lives at "/cool-app" rather than at the root "/"
basePath="cool-app"
// Re-fetch session every 5 minutes
refetchInterval={5 * 60}
// Re-fetches session when window is focused
refetchOnWindowFocus={true}
>
<Component {...pageProps} />
</SessionProvider>
)
}
```
:::note
**These options have no effect on clients that are not signed in.**
Every tab/window maintains its own copy of the local session state; the session is not stored in shared storage like localStorage or sessionStorage. Any update in one tab/window triggers a message to other tabs/windows to update their own session state.
Using low values for `refetchInterval` will increase network traffic and load on authenticated clients and may impact hosting costs and performance.
:::
#### Base path
If you are using a custom base path, and your application entry point is not at the root of the domain "/" but something else, for example "/my-app/" you can use the `basePath` prop to make NextAuth.js aware of that so that all redirects and session handling work as expected.
#### Refetch interval
The `refetchInterval` option can be used to contact the server to avoid a session expiring.
When `refetchInterval` is set to `0` (the default) there will be no session polling.
If set to any value other than zero, it specifies in seconds how often the client should contact the server to update the session state. If the session state has expired when it is triggered, all open tabs/windows will be updated to reflect this.
The value for `refetchInterval` should always be lower than the value of the session `maxAge` [session option](/reference/configuration/auth-config#session).
By default, session polling will keep trying, even when the device has no internet access. To circumvent this, you can also set `refetchWhenOffline` to `false`. This will use [`navigator.onLine`](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/onLine) to only poll when the device is online.
#### Refetch On Window Focus
The `refetchOnWindowFocus` option can be used to control whether it automatically updates the session state when you switch a focus on tabs/windows.
When `refetchOnWindowFocus` is set to `true` (the default) tabs/windows will be updated and initialize the components' state when they gain or lose focus.
However, if it was set to `false`, it stops re-fetching the session and the components will stay as it is.
:::note
See [**the Next.js documentation**](https://nextjs.org/docs/advanced-features/custom-app) for more information on **\_app.js** in Next.js applications.
:::
---
## useSession()
- Client Side: **Yes**
- Server Side: No
The `useSession()` React Hook in the NextAuth.js client is the easiest way to check if someone is signed in.
Make sure that [`<SessionProvider>`](#sessionprovider) is added to `pages/_app.js`.
#### Example
```jsx
import { useSession } from "next-auth/react"
export default function Component() {
const { data: session, status } = useSession()
if (status === "authenticated") {
return <p>Signed in as {session.user.email}</p>
}
return <a href="/api/auth/signin">Sign in</a>
}
```
`useSession()` returns an object containing two values: `data` and `status`:
- **`data`**: This can be three values: [`Session`](https://github.com/nextauthjs/next-auth/blob/8ff4b260143458c5d8a16b80b11d1b93baa0690f/types/index.d.ts#L437-L444) / `undefined` / `null`.
- when the session hasn't been fetched yet, `data` will `undefined`
- in case it failed to retrieve the session, `data` will be `null`
- in case of success, `data` will be [`Session`](https://github.com/nextauthjs/next-auth/blob/8ff4b260143458c5d8a16b80b11d1b93baa0690f/types/index.d.ts#L437-L444).
- **`status`**: enum mapping to three possible session states: `"loading" | "authenticated" | "unauthenticated"`
### Require session
Due to the way how Next.js handles `getServerSideProps` and `getInitialProps`, every protected page load has to make a server-side request to check if the session is valid and then generate the requested page (SSR). This increases server load, and if you are good with making the requests from the client, there is an alternative. You can use `useSession` in a way that makes sure you always have a valid session. If after the initial loading state there was no session found, you can define the appropriate action to respond.
The default behavior is to redirect the user to the sign-in page, from where - after a successful login - they will be sent back to the page they started on. You can also define an `onUnauthenticated()` callback, if you would like to do something else:
#### Example
```jsx title="pages/protected.jsx"
import { useSession } from "next-auth/react"
export default function Admin() {
const { status } = useSession({
required: true,
onUnauthenticated() {
// The user is not authenticated, handle it here.
},
})
if (status === "loading") {
return "Loading or not authenticated..."
}
return "User is logged in"
}
```
### Custom Client Session Handling
Due to the way Next.js handles `getServerSideProps` / `getInitialProps`, every protected page load has to make a server-side request to check if the session is valid and then generate the requested page. This alternative solution allows for showing a loading state on the initial check and every page transition afterward will be client-side, without having to check with the server and regenerate pages.
```js title="pages/admin.jsx"
export default function AdminDashboard() {
const { data: session } = useSession()
// session is always non-null inside this page, all the way down the React tree.
return "Some super secret dashboard"
}
AdminDashboard.auth = true
```
```jsx title="pages/_app.jsx"
export default function App({
Component,
pageProps: { session, ...pageProps },
}) {
return (
<SessionProvider session={session}>
{Component.auth ? (
<Auth>
<Component {...pageProps} />
</Auth>
) : (
<Component {...pageProps} />
)}
</SessionProvider>
)
}
function Auth({ children }) {
// if `{ required: true }` is supplied, `status` can only be "loading" or "authenticated"
const { status } = useSession({ required: true })
if (status === "loading") {
return <div>Loading...</div>
}
return children
}
```
It can be easily extended/modified to support something like an options object for role based authentication on pages. An example:
```jsx title="pages/admin.jsx"
AdminDashboard.auth = {
role: "admin",
loading: <AdminLoadingSkeleton />,
unauthorized: "/login-with-different-user", // redirect to this url
}
```
Because of how `_app` is written, it won't unnecessarily contact the `/api/auth/session` endpoint for pages that do not require authentication.
More information can be found in the following [GitHub Issue](https://github.com/nextauthjs/next-auth/issues/1210).
### NextAuth.js + React-Query
There is also an alternative client-side API library based upon [`react-query`](https://www.npmjs.com/package/react-query) available under [`nextauthjs/react-query`](https://github.com/nextauthjs/react-query).
If you use `react-query` in your project already, you can leverage it with NextAuth.js to handle the client-side session management for you as well. This replaces NextAuth.js's native `useSession` and `SessionProvider` from `next-auth/react`.
See repository [`README`](https://github.com/nextauthjs/react-query) for more details.

View File

@@ -1,9 +1,9 @@
---
title: SvelteKit
title: SvelteKit Auth
---
:::warning
`@auth/sveltekit` is currently experimental. 🏗
`@auth/sveltekit` is currently experimental.
:::
## Installation
@@ -28,6 +28,8 @@ export const handle = SvelteKitAuth({
Don't forget to set the `AUTH_SECRET` [environment variable](https://kit.svelte.dev/docs/modules#$env-static-private). This should be a random 32 character string. On unix systems you can use `openssl rand -hex 32` or check out `https://generate-secret.vercel.app/32`.
When deploying your app outside Vercel, set the `AUTH_TRUST_HOST` variable to `true` for other hosting providers like Cloudflare Pages or Netlify.
## Signing in and signing out
```ts

View File

@@ -0,0 +1,7 @@
---
title: Client
---
:::warning WIP
`@auth/nextjs/client` is work in progress. For now, please use [NextAuth.js Client API](https://next-auth.js.org/getting-started/client).
:::

View File

@@ -1,276 +1,7 @@
---
title: Next.js
title: Next.js Auth
---
## `unstable_getServerSession`
:::warning
This feature is experimental and may be removed or changed in the future.
:::warning WIP
`@auth/nextjs` is work in progress. For now, please use [NextAuth.js](https://next-auth.js.org).
:::
When calling from server-side i.e. in API routes or in `getServerSideProps`, we recommend using this function instead of `getSession` to retrieve the `session` object. This method is especially useful when you are using NextAuth.js with a database. This method can _drastically_ reduce response time when used over `getSession` server-side, due to avoiding an extra `fetch` to an API Route (this is generally [not recommended in Next.js](https://nextjs.org/docs/basic-features/data-fetching/get-server-side-props#getserversideprops-or-api-routes)). In addition, `unstable_getServerSession` will correctly update the cookie expiry time and update the session content if `callbacks.jwt` or `callbacks.session` changed something.
Otherwise, if you only want to get the session token, see [`getToken`](/guides/basics/securing-pages-and-api-routes#using-gettoken).
`unstable_getServerSession` requires passing the same object you would pass to `NextAuth` when initializing NextAuth.js. To do so, you can export your NextAuth.js options in the following way:
In `[...nextauth].ts`:
```ts
import { NextAuth } from "next-auth"
import type { NextAuthOptions } from "next-auth"
export const authOptions: NextAuthOptions = {
// your configs
}
export default NextAuth(authOptions)
```
### In `getServerSideProps`:
```js
import { authOptions } from "pages/api/auth/[...nextauth]"
import { unstable_getServerSession } from "next-auth/next"
export async function getServerSideProps(context) {
const session = await unstable_getServerSession(
context.req,
context.res,
authOptions
)
if (!session) {
return {
redirect: {
destination: "/",
permanent: false,
},
}
}
return {
props: {
session,
},
}
}
```
### In API Routes:
```js
import { authOptions } from "pages/api/auth/[...nextauth]"
import { unstable_getServerSession } from "next-auth/next"
export async function handler(req, res) {
const session = await unstable_getServerSession(req, res, authOptions)
if (!session) {
res.status(401).json({ message: "You must be logged in." })
return
}
return res.json({
message: "Success",
})
}
```
### In `app/` directory:
You can also use `unstable_getServerSession` in Next.js' server components:
```tsx
import { unstable_getServerSession } from "next-auth/next"
import { authOptions } from "pages/api/auth/[...nextauth]"
export default async function Page() {
const session = await unstable_getServerSession(authOptions)
return <pre>{JSON.stringify(session, null, 2)}</pre>
}
```
:::warning
Currently, the underlying Next.js `cookies()` method does [only provides read access](/reference/configuration/auth-config#cookies) to the request cookies. This means that the `expires` value is stripped away from `session` in Server Components. Furthermore, there is a hard expiry on sessions, after which the user will be required to sign in again. (The default expiry is 30 days).
:::
## Middleware
You can use a Next.js Middleware with NextAuth.js to protect your site.
Next.js 12 has introduced [Middleware](https://nextjs.org/docs/middleware). It is a way to run logic before accessing any page, even when they are static. On platforms like Vercel, Middleware is run at the [Edge](https://nextjs.org/docs/api-reference/edge-runtime).
If the following options look familiar, this is because they are a subset of [these options](/reference/configuration/auth-config). You can extract these to a common configuration object to reuse them. In the future, we would like to be able to run everything in Middleware. (See [Caveats](#caveats)).
You can get the `withAuth` middleware function from `next-auth/middleware` either as a default or a named import:
### Prerequisites
You must set the same secret in the middleware that you use in NextAuth. The easiest way is to set the [`NEXTAUTH_SECRET`](/reference/configuration/auth-config#nextauth_secret) environment variable. It will be picked up by both the [Auth.js config](/reference/configuration/auth-config), as well as the middleware config.
Alternatively, you can provide the secret using the [`secret`](#secret) option in the middleware config.
**We strongly recommend** replacing the `secret` value completely with this `NEXTAUTH_SECRET` environment variable.
### Basic usage
The most simple usage is when you want to require authentication for your entire site. You can add a `middleware.js` file with the following:
```js
export { default } from "next-auth/middleware"
```
That's it! Your application is now secured. 🎉
If you only want to secure certain pages, export a `config` object with a `matcher`:
```js
export { default } from "next-auth/middleware"
export const config = { matcher: ["/dashboard"] }
```
Now you will still be able to visit every page, but only `/dashboard` will require authentication.
If a user is not logged in, the default behavior is to redirect them to the sign-in page.
---
### `callbacks`
- **Required:** No
#### Description
Callbacks are asynchronous functions you can use to control what happens when an action is performed.
#### Example (default value)
```js
callbacks: {
authorized({ req , token }) {
if(token) return true // If there is a token, the user is authenticated
}
}
```
---
### `pages`
- **Required**: _No_
#### Description
Specify URLs to be used if you want to create custom sign in, and error pages. Pages specified will override the corresponding built-in page.
:::note
This should match the `pages` configuration that's found in `[...nextauth].ts`.
:::
#### Example (default value)
```js
pages: {
signIn: '/api/auth/signin',
error: '/api/auth/error',
}
```
See the documentation for the [`pages` option](/reference/configuration/auth-config#pages) for more information.
---
### `secret`
- **Required**: _No_
#### Description
The same `secret` used in the [Auth.js config](/reference/configuration/auth-config).
#### Example (default value)
```js
secret: process.env.NEXTAUTH_SECRET
```
---
### Advanced usage
NextAuth.js Middleware is very flexible, there are multiple ways to use it.
:::note
If you do not define the options, NextAuth.js will use the default values for the omitted options.
:::
#### wrap middleware
```ts title="middleware.ts"
import { withAuth } from "next-auth/middleware"
export default withAuth(
// `withAuth` augments your `Request` with the user's token.
function middleware(req) {
console.log(req.nextauth.token)
},
{
callbacks: {
authorized: ({ token }) => token?.role === "admin",
},
}
)
export const config = { matcher: ["/admin"] }
```
The `middleware` function will only be invoked if the `authorized` callback returns `true`.
---
#### Custom JWT decode method
If you have a custom jwt decode method set in `[...nextauth].ts`, you must also pass the same `decode` method to `withAuth` in order to read the custom-signed JWT correctly. You may want to extract the encode/decode logic to a separate function for consistency.
``
```ts title="/api/auth/[...nextauth].ts"
import type { NextAuthOptions } from "next-auth"
import NextAuth from "next-auth"
import jwt from "jsonwebtoken"
export const authOptions: NextAuthOptions = {
providers: [...],
jwt: {
async encode({ secret, token }) {
return jwt.sign(token, secret)
},
async decode({ secret, token }) {
return jwt.verify(token, secret)
},
},
}
export default NextAuth(authOptions)
```
And:
```ts title="middleware.ts"
import withAuth from "next-auth/middleware"
import { authOptions } from "pages/api/auth/[...nextauth]"
export default withAuth({
jwt: { decode: authOptions.jwt },
callbacks: {
authorized: ({ token }) => !!token,
},
})
```
### Caveats
- Currently only supports session verification, as parts of the sign-in code need to run in a Node.js environment. In the future, we would like to make sure that NextAuth.js can fully run at the [Edge](https://nextjs.org/docs/api-reference/edge-runtime)
- Only supports the `"jwt"` [session strategy](/reference/configuration/auth-config#session). We need to wait until databases at the Edge become mature enough to ensure a fast experience. (If you know of an Edge-compatible database, we would like if [you proposed a new Adapter](/guides/adapters/creating-a-database-adapter))

View File

@@ -40,4 +40,4 @@ providers: [
:::warning
The United Effects API does not return the user name or image by design, so this provider will return null for both. United Effects prioritizes user personal information security above all and has built a secured profile access request system separate from the provider API.
:::
:::

View File

@@ -1,24 +1,10 @@
---
title: List of database adapters
sidebar_label: Overview
title: Database Adapters
---
Auth.js comes with a lot of built-in database adapters to suit your needs. Here's the full list. Navigate to an adapter reference page to learn how to integrate with it:
- [Dgraph](/reference/adapters/dgraph)
- [DynamoDB](/reference/adapters/dynamodb)
- [FaunaDB](/reference/adapters/fauna)
- [Firebase](/reference/adapters/firebase)
- [MikroORM](/reference/adapters/mikro-orm)
- [Neo4j](/reference/adapters/neo4j)
- [PouchDB](/reference/adapters/pouchdb)
- [Prisma](/reference/adapters/prisma)
- [Sequelize](/reference/adapters/sequelize)
- [Supabase](/reference/adapters/supabase)
- [TypeORM](/reference/adapters/typeorm)
- [Upstash Redis](/reference/adapters/upstash-redis)
- [Xata](/reference/adapters/xata)
:::warning WIP
`@auth/*-adapter` is work in progress. for the time being, please go to [NextAuth.js Adapters](https://next-auth.js.org/adapters/overview).
:::
In case you want to [create your own custom adapter](/guides/adapters/creating-a-database-adapter) or configure one of the existing adapters, make sure you are familiar with the Auth.js uses when talking to adapters:
- [Database model structure](/reference/adapters/models)

View File

@@ -3,7 +3,7 @@ id: models
title: Models
---
NextAuth.js can be used with any database. Models tell you what structures NextAuth.js expects from your database. Models will vary slightly depending on which adapter you use, but in general, will look something like this. Each adapter's model/schema will be slightly adapted for its needs, but will look very much like this schema below:
Auth.js can be used with any database. Models tell you what structures Auth.js expects from your database. Models will vary slightly depending on which adapter you use, but in general, will look something like this. Each adapter's model/schema will be slightly adapted for its needs, but will look very much like this schema below:
```mermaid
erDiagram
@@ -48,7 +48,7 @@ erDiagram
More information about each Model / Table can be found below.
:::note
You can [create your own adapter](/guides/adapters/creating-a-database-adapter) if you want to use NextAuth.js with a database that is not supported out of the box, or you have to change fields on any of the models.
You can [create your own adapter](/guides/adapters/creating-a-database-adapter) if you want to use Auth.js with a database that is not supported out of the box, or you have to change fields on any of the models.
:::
---
@@ -106,7 +106,7 @@ A single User can have multiple open Verification Tokens (e.g. to sign in to dif
It has been designed to be extendable for other verification purposes in the future (e.g. 2FA / short codes).
:::note
NextAuth.js makes sure that every token is usable only once, and by default has a short (1 day, can be configured by [`maxAge`](/reference/providers/email)) lifetime. If your user did not manage to finish the sign-in flow in time, they will have to start the sign-in process again.
Auth.js makes sure that every token is usable only once, and by default has a short (1 day, can be configured by [`maxAge`](/reference/providers/email)) lifetime. If your user did not manage to finish the sign-in flow in time, they will have to start the sign-in process again.
:::
:::tip
@@ -115,4 +115,4 @@ Due to users forgetting or failing at the sign-in flow, you might end up with un
## RDBMS Naming Convention
In the NextAuth.js v4 some schemas for the providers which support classic RDBMS type databases, like Prisma and TypeORM, have ended up with column names with mixed casing, i.e. snake_case and camelCase. If this is an issue for you or your underlying database system, please take a look at the "Naming Convention" section in the Prisma or TypeORM page.
In the Auth.js v4 some schemas for the providers which support classic RDBMS type databases, like Prisma and TypeORM, have ended up with column names with mixed casing, i.e. snake_case and camelCase. If this is an issue for you or your underlying database system, please take a look at the "Naming Convention" section in the Prisma or TypeORM page.

Some files were not shown because too many files have changed in this diff Show More