Compare commits
40 Commits
ndom91/doc
...
docs/provi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5d815ce593 | ||
|
|
25be00b749 | ||
|
|
b31f2af66c | ||
|
|
71bb6f2590 | ||
|
|
f28b58d49d | ||
|
|
6c07331cc5 | ||
|
|
c8ef94b2be | ||
|
|
75a59fbd92 | ||
|
|
3dd47b0735 | ||
|
|
4dc1d421f8 | ||
|
|
99ca67f1cf | ||
|
|
a087df8494 | ||
|
|
1aa4994de6 | ||
|
|
88023f69b9 | ||
|
|
b02057a72d | ||
|
|
400da8c766 | ||
|
|
b48104801b | ||
|
|
ccbbc800d2 | ||
|
|
d7888263ca | ||
|
|
47d3151410 | ||
|
|
7d264860ab | ||
|
|
6184b936f5 | ||
|
|
1954258a0a | ||
|
|
c580f0db22 | ||
|
|
d1cf701ed9 | ||
|
|
69398e2d3a | ||
|
|
856b5c50fc | ||
|
|
2830b7de5b | ||
|
|
40a0faa586 | ||
|
|
a6b4d958ac | ||
|
|
cc13df9d51 | ||
|
|
06b8d4772c | ||
|
|
d644d1fcbf | ||
|
|
380f2de961 | ||
|
|
dc5f3e1873 | ||
|
|
93f3fcd1b7 | ||
|
|
1d9b9ba47c | ||
|
|
8f6108f230 | ||
|
|
15943d6696 | ||
|
|
81589bf738 |
@@ -1,74 +0,0 @@
|
||||
.eslintrc.js
|
||||
.cache-loader
|
||||
.DS_Store
|
||||
.pnpm-debug.log
|
||||
.turbo
|
||||
.vscode/generated*
|
||||
/_work
|
||||
/actions-runner
|
||||
node_modules
|
||||
patches
|
||||
pnpm-lock.yaml
|
||||
.github/actions/issue-validator/index.mjs
|
||||
*.cjs
|
||||
*.js
|
||||
*.d.ts
|
||||
*.d.ts.map
|
||||
|
||||
.svelte-kit
|
||||
.next
|
||||
.nuxt
|
||||
|
||||
# --------------- Docs ---------------
|
||||
|
||||
.docusaurus
|
||||
build
|
||||
docs/pages/reference/core
|
||||
docs/pages/reference/sveltekit
|
||||
docs/pages/reference/adapter
|
||||
static
|
||||
|
||||
# TODO: Enable
|
||||
docs-nextra
|
||||
|
||||
# --------------- Packages ---------------
|
||||
|
||||
coverage
|
||||
dist
|
||||
|
||||
# @auth/core
|
||||
packages/core/src/providers/oauth-types.ts
|
||||
packages/core/src/lib/pages/styles.ts
|
||||
|
||||
# @auth/sveltekit
|
||||
packages/frameworks-sveltekit/package
|
||||
packages/frameworks-sveltekit/vite.config.{js,ts}.timestamp-*
|
||||
|
||||
# next-auth
|
||||
packages/next-auth/src/providers/oauth-types.ts
|
||||
packages/next-auth/css/index.css
|
||||
|
||||
|
||||
# Adapters
|
||||
.branches
|
||||
db.sqlite
|
||||
dev.db
|
||||
dynamodblocal-bin
|
||||
firebase-debug.log
|
||||
firestore-debug.log
|
||||
migrations
|
||||
test.schema.gql
|
||||
|
||||
# --------------- Apps ---------------
|
||||
|
||||
|
||||
# Examples should have their own Prettier config since they are templates too
|
||||
apps/example-sveltekit
|
||||
|
||||
# Development app
|
||||
apps
|
||||
|
||||
|
||||
# --------------- Tests ---------------
|
||||
# TODO: these should be linted
|
||||
packages/**/*test*
|
||||
75
.eslintrc.js
@@ -1,75 +0,0 @@
|
||||
// @ts-check
|
||||
|
||||
/** @type {import("eslint").ESLint.ConfigData} */
|
||||
module.exports = {
|
||||
env: { browser: true, es2022: true, node: true },
|
||||
extends: ["eslint:recommended", "prettier"],
|
||||
overrides: [
|
||||
{
|
||||
files: ["*.ts", "*.tsx"],
|
||||
parser: "@typescript-eslint/parser",
|
||||
parserOptions: {
|
||||
project: ["./packages/**/tsconfig.json", "./apps/**/tsconfig.json"],
|
||||
},
|
||||
settings: { react: { version: "18" } },
|
||||
extends: [
|
||||
"plugin:react/recommended",
|
||||
"plugin:react/jsx-runtime",
|
||||
"standard-with-typescript",
|
||||
"prettier",
|
||||
],
|
||||
rules: {
|
||||
"@typescript-eslint/explicit-function-return-type": "off",
|
||||
"@typescript-eslint/method-signature-style": "off",
|
||||
"@typescript-eslint/naming-convention": "off",
|
||||
"@typescript-eslint/no-non-null-assertion": "off",
|
||||
"@typescript-eslint/restrict-template-expressions": "off",
|
||||
"@typescript-eslint/strict-boolean-expressions": "off",
|
||||
"react/prop-types": "off",
|
||||
"react/no-unescaped-entities": "off",
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ["*.test.ts", "*.test.js"],
|
||||
extends: ["plugin:jest/recommended"],
|
||||
env: { jest: true },
|
||||
},
|
||||
// {
|
||||
// files: ["docs/**"],
|
||||
// plugins: ["@docusaurus"],
|
||||
// extends: ["plugin:@docusaurus/recommended"],
|
||||
// },
|
||||
{
|
||||
// TODO: Expand to all packages
|
||||
files: ["packages/{core,sveltekit}/*.ts"],
|
||||
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/frameworks-sveltekit"],
|
||||
plugins: ["svelte3"],
|
||||
overrides: [{ files: ["*.svelte"], processor: "svelte3/svelte3" }],
|
||||
settings: {
|
||||
"svelte3/typescript": () => require("typescript"),
|
||||
},
|
||||
parserOptions: { sourceType: "module", ecmaVersion: 2020 },
|
||||
env: { browser: true, es2017: true, node: true },
|
||||
},
|
||||
],
|
||||
parserOptions: {
|
||||
sourceType: "module",
|
||||
ecmaVersion: "latest",
|
||||
ecmaFeatures: { jsx: true },
|
||||
},
|
||||
root: true,
|
||||
}
|
||||
2
.github/pr-labeler.yml
vendored
@@ -2,7 +2,7 @@
|
||||
adapters: ["packages/core/src/adapters.ts", "packages/adapter-*/**/*"]
|
||||
core: ["packages/core/src/**/*"]
|
||||
dgraph: ["packages/adapter-dgraph/**/*"]
|
||||
documentation: ["packages/docs/pages/**/*"]
|
||||
documentation: ["packages/docs/docs/**/*"]
|
||||
dynamodb: ["packages/adapter-dynamodb/**/*"]
|
||||
examples: ["apps/examples/**/*"]
|
||||
fauna: ["packages/adapter-fauna/**/*"]
|
||||
|
||||
6
.gitignore
vendored
@@ -82,7 +82,8 @@ packages/core/src/providers/oauth-types.ts
|
||||
packages/core/lib
|
||||
packages/core/providers
|
||||
packages/core/src/lib/pages/styles.ts
|
||||
docs/pages/reference/core
|
||||
docs/docs/reference/core
|
||||
docs/docs/reference/sveltekit
|
||||
|
||||
|
||||
# SvelteKit
|
||||
@@ -92,8 +93,7 @@ packages/frameworks-sveltekit/.svelte-kit
|
||||
packages/frameworks-sveltekit/package
|
||||
packages/frameworks-sveltekit/vite.config.js.timestamp-*
|
||||
packages/frameworks-sveltekit/vite.config.ts.timestamp-*
|
||||
docs/pages/reference/sveltekit
|
||||
|
||||
# Adapters
|
||||
|
||||
docs/pages/reference/adapter
|
||||
docs/docs/reference/adapter
|
||||
@@ -13,14 +13,16 @@ pnpm-lock.yaml
|
||||
*.d.ts.map
|
||||
|
||||
.svelte-kit
|
||||
.next
|
||||
.nuxt
|
||||
|
||||
# --------------- Docs ---------------
|
||||
|
||||
.next
|
||||
docs/pages/reference/core
|
||||
docs/pages/reference/sveltekit
|
||||
docs/pages/reference/adapter
|
||||
.docusaurus
|
||||
build
|
||||
docs/docs/reference/core
|
||||
docs/docs/reference/sveltekit
|
||||
static
|
||||
docs/providers.json
|
||||
|
||||
# --------------- Packages ---------------
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
// @ts-check
|
||||
|
||||
/** @type {import("prettier").Config} */
|
||||
module.exports = {
|
||||
semi: false,
|
||||
singleQuote: false,
|
||||
overrides: [
|
||||
{
|
||||
files: [
|
||||
"apps/dev/nextjs/pages/api/auth/[...nextauth].ts",
|
||||
"docs/{sidebars,docusaurus.config}.js",
|
||||
],
|
||||
options: { printWidth: 150 },
|
||||
},
|
||||
{
|
||||
files: ["**/*package.json"],
|
||||
options: {
|
||||
trailingComma: "none",
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -52,6 +52,10 @@ TWITTER_SECRET=
|
||||
WIKIMEDIA_ID=
|
||||
WIKIMEDIA_SECRET=
|
||||
|
||||
# Yandex OAuth. new app -> https://oauth.yandex.com/client/new/id
|
||||
YANDEX_ID=
|
||||
YANDEX_SECRET=
|
||||
|
||||
# Example configuration for a Gmail account (will need SMTP enabled)
|
||||
EMAIL_SERVER=smtps://user@gmail.com:password@smtp.gmail.com:465
|
||||
EMAIL_FROM=user@gmail.com
|
||||
|
||||
@@ -34,6 +34,7 @@ import Spotify from "@auth/core/providers/spotify"
|
||||
import Trakt from "@auth/core/providers/trakt"
|
||||
import Twitch from "@auth/core/providers/twitch"
|
||||
import Twitter from "@auth/core/providers/twitter"
|
||||
import Yandex from "@auth/core/providers/yandex"
|
||||
import Vk from "@auth/core/providers/vk"
|
||||
import Wikimedia from "@auth/core/providers/wikimedia"
|
||||
import WorkOS from "@auth/core/providers/workos"
|
||||
@@ -120,6 +121,7 @@ export const authConfig: AuthConfig = {
|
||||
Twitch({ clientId: process.env.TWITCH_ID, clientSecret: process.env.TWITCH_SECRET }),
|
||||
Twitter({ clientId: process.env.TWITTER_ID, clientSecret: process.env.TWITTER_SECRET }),
|
||||
// TwitterLegacy({ clientId: process.env.TWITTER_LEGACY_ID, clientSecret: process.env.TWITTER_LEGACY_SECRET }),
|
||||
Yandex({ clientId: process.env.YANDEX_ID, clientSecret: process.env.YANDEX_SECRET }),
|
||||
Vk({ clientId: process.env.VK_ID, clientSecret: process.env.VK_SECRET }),
|
||||
Wikimedia({ clientId: process.env.WIKIMEDIA_ID, clientSecret: process.env.WIKIMEDIA_SECRET }),
|
||||
WorkOS({ clientId: process.env.WORKOS_ID, clientSecret: process.env.WORKOS_SECRET }),
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { unstable_getServerSession } from "next-auth/next"
|
||||
import { getServerSession } from "next-auth/next"
|
||||
import { authOptions } from "./api/auth/[...nextauth]"
|
||||
import Layout from "../components/layout"
|
||||
|
||||
@@ -38,7 +38,7 @@ export default function ServerSidePage() {
|
||||
export async function getServerSideProps(context: GetServerSidePropsContext) {
|
||||
return {
|
||||
props: {
|
||||
session: await unstable_getServerSession(
|
||||
session: await getServerSession(
|
||||
context.req,
|
||||
context.res,
|
||||
authOptions
|
||||
|
||||
@@ -10,13 +10,13 @@
|
||||
"clean": "gatsby clean"
|
||||
},
|
||||
"dependencies": {
|
||||
"dotenv": "^16.0.0",
|
||||
"gatsby": "next",
|
||||
"dotenv": "16.0.0",
|
||||
"gatsby": "5.8.0-next.3",
|
||||
"next-auth": "workspace:*",
|
||||
"react": "^18",
|
||||
"react-dom": "^18"
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"vercel": "^23.1.2"
|
||||
"vercel": "23.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"extends": "next/core-web-vitals"
|
||||
}
|
||||
66
docs/README.md
Normal file
@@ -0,0 +1,66 @@
|
||||
<p align="center">
|
||||
<br/>
|
||||
<a href="https://authjs.dev" target="_blank"><img width="150px" src="https://authjs.dev/img/logo/logo-sm.png" /></a>
|
||||
<h3 align="center">Auth.js</h3>
|
||||
<p align="center">Authentication for Next.js</p>
|
||||
<p align="center">
|
||||
Open Source. Full Stack. Own Your Data.
|
||||
</p>
|
||||
<p align="center" style="align: center;">
|
||||
<a href="https://github.com/nextauthjs/next-auth/actions/workflows/release.yml?query=workflow%3ARelease">
|
||||
<img src="https://github.com/nextauthjs/next-auth/actions/workflows/release.yml/badge.svg" alt="Release" />
|
||||
</a>
|
||||
<a href="https://packagephobia.com/result?p=@auth/core">
|
||||
<img src="https://packagephobia.com/badge?p=@auth/core" alt="Bundle Size"/>
|
||||
</a>
|
||||
<a href="https://www.npmtrends.com/@auth/core">
|
||||
<img src="https://img.shields.io/npm/dm/@auth/core" alt="Downloads" />
|
||||
</a>
|
||||
<a href="https://github.com/nextauthjs/next-auth/stargazers">
|
||||
<img src="https://img.shields.io/github/stars/nextauthjs/next-auth" alt="Github Stars" />
|
||||
</a>
|
||||
<a href="https://www.npmjs.com/package/@auth/core">
|
||||
<img src="https://img.shields.io/github/v/release/nextauthjs/next-auth?label=latest" alt="Github Stable Release" />
|
||||
</a>
|
||||
</p>
|
||||
</p>
|
||||
|
||||
## Overview
|
||||
|
||||
This is the repository for the documentation page for Auth.js!
|
||||
|
||||
NextAuth.js is a complete open source authentication solution for [Next.js](http://nextjs.org/) applications.
|
||||
|
||||
This documentation site is based on the [Docusaurus](https://docusaurus.io) framework.
|
||||
|
||||
## Getting Started
|
||||
|
||||
To start a local environment of this project, please do the following.
|
||||
|
||||
1. Clone the repository.
|
||||
|
||||
```bash
|
||||
$ git clone https://github.com/nextauthjs/docs.git
|
||||
```
|
||||
|
||||
2. Install dependencies
|
||||
|
||||
```bash
|
||||
$ npm install
|
||||
```
|
||||
|
||||
3. Start the development server
|
||||
|
||||
```bash
|
||||
$ npm start
|
||||
```
|
||||
|
||||
And thats all! Now you should have a local copy of this docs site running at [localhost:3000](http://localhost:3000)!
|
||||
|
||||
## Contributing
|
||||
|
||||
We're open to all community contributions! If you'd like to contribute in any way, please first read our [Contributing Guide](https://github.com/nextauthjs/.github/blob/main/CONTRIBUTING.md).
|
||||
|
||||
## License
|
||||
|
||||
ISC
|
||||
@@ -1,19 +0,0 @@
|
||||
<!-- <svg width="1077" height="990" viewBox="0 0 1077 990" fill="none" xmlns="http://www.w3.org/2000/svg"> -->
|
||||
<!-- <path d="M909.079 176.687C486.468 1429.32 94.8519 797.145 -245.666 989.191L-273.518 122.311C-98.0847 109.104 255.784 81.3405 267.79 75.9479C282.798 69.2072 1153.31 -485.661 1071.51 -140.889C1022.28 -26.4819 1001.45 -97.0987 909.079 176.687Z" fill="url(#paint0_linear_228_76)" fill-opacity="1" /> -->
|
||||
<!-- <defs> -->
|
||||
<!-- <linearGradient id="paint0_linear_228_76" x1="588.47" y1="791.265" x2="238.137" y2="497.91" gradientUnits="userSpaceOnUse"> -->
|
||||
<!-- <stop stop-color="#FF4400"/> -->
|
||||
<!-- <stop offset="1" stop-color="#111" /> -->
|
||||
<!-- </linearGradient> -->
|
||||
<!-- </defs> -->
|
||||
<!-- </svg> -->
|
||||
<svg width="1056" height="855" viewBox="0 0 1056 855" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M888.078 42.3027C465.467 1294.94 73.851 662.761 -266.667 854.807L-294.519 -12.0732C-119.086 -25.2807 234.783 -53.0438 246.789 -58.4364C261.797 -65.1771 1132.31 -620.045 1050.51 -275.273C1001.28 -160.866 980.447 -231.483 888.078 42.3027Z" fill="url(#paint0_radial_228_76)"/>
|
||||
<defs>
|
||||
<radialGradient id="paint0_radial_228_76" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(666.999 571.116) rotate(-129.513) scale(513.947 862.777)">
|
||||
<stop stop-color="#FF4400"/>
|
||||
<stop offset="1" stop-color="#111111"/>
|
||||
</radialGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.4 KiB |
@@ -1,20 +0,0 @@
|
||||
<!-- <svg width="1405" height="1025" viewBox="0 0 1405 1025" fill="none" xmlns="http://www.w3.org/2000/svg"> -->
|
||||
<!-- <path d="M1180.05 977.4C483.802 708.04 103.247 143.506 0 -105.091L1102.61 -196C1418.53 307.367 1876.29 1246.76 1180.05 977.4Z" fill="url(#paint0_linear_228_83)" fill-opacity="0.44"/> -->
|
||||
<!-- <defs> -->
|
||||
<!-- <linearGradient id="paint0_linear_228_83" x1="185.171" y1="460.565" x2="641.405" y2="-62.9701" gradientUnits="userSpaceOnUse"> -->
|
||||
<!-- <stop stop-color="#BB44CC"/> -->
|
||||
<!-- <stop offset="1" stop-color="#BB44CC" stop-opacity="0"/> -->
|
||||
<!-- </linearGradient> -->
|
||||
<!-- </defs> -->
|
||||
<!-- </svg> -->
|
||||
|
||||
<svg width="1405" height="1025" viewBox="0 0 1405 1025" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M1180.05 977.4C483.802 708.04 103.247 143.506 0 -105.091L1102.61 -196C1418.53 307.367 1876.29 1246.76 1180.05 977.4Z" fill="url(#paint0_radial_228_83)"/>
|
||||
<defs>
|
||||
<radialGradient id="paint0_radial_228_83" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(498 619) rotate(-46.5881) scale(548.572 1194.34)">
|
||||
<stop stop-color="#BB44CC"/>
|
||||
<stop offset="1" stop-color="#111111"/>
|
||||
</radialGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
@@ -1,20 +0,0 @@
|
||||
<!-- <svg width="2402" height="275" viewBox="0 0 2402 275" fill="none" xmlns="http://www.w3.org/2000/svg"> -->
|
||||
<!-- <path d="M305.668 155.376C1150.52 -387.169 3270.85 708.01 2011.14 262.274L1847.48 804.627C1613.84 721.267 1142.31 553.804 1125.29 550.832C1104 547.117 -168.361 431.431 18.8067 264.119C109.949 220.108 121.011 273.958 305.668 155.376Z" fill="url(#paint0_linear_228_78)" fill-opacity="0.66"/> -->
|
||||
<!-- <defs> -->
|
||||
<!-- <linearGradient id="paint0_linear_228_78" x1="869.047" y1="-51.7999" x2="921.583" y2="353.448" gradientUnits="userSpaceOnUse"> -->
|
||||
<!-- <stop stop-color="#44BBCC"/> -->
|
||||
<!-- <stop offset="1" stop-color="#44BBCC" stop-opacity="0.12"/> -->
|
||||
<!-- </linearGradient> -->
|
||||
<!-- </defs> -->
|
||||
<!-- </svg> -->
|
||||
|
||||
<svg width="2402" height="275" viewBox="0 0 2402 275" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M305.668 155.376C1150.52 -387.169 3270.85 708.01 2011.14 262.274L1847.48 804.627C1613.84 721.267 1142.31 553.804 1125.29 550.832C1104 547.117 -168.361 431.431 18.8067 264.119C109.949 220.108 121.011 273.958 305.668 155.376Z" fill="url(#paint0_radial_228_78)"/>
|
||||
<defs>
|
||||
<radialGradient id="paint0_radial_228_78" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(883.5 -66) rotate(93.0267) scale(757.557 879.417)">
|
||||
<stop stop-color="#44BBCC"/>
|
||||
<stop offset="1" stop-color="#111111"/>
|
||||
</radialGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.4 KiB |
@@ -1,66 +0,0 @@
|
||||
import { useState, useEffect } from "react"
|
||||
import { motion } from "framer-motion"
|
||||
|
||||
const clamp = (num, min, max) => Math.min(Math.max(num, min), max)
|
||||
|
||||
export default function Marquee({ files }) {
|
||||
const [{ width, height }, setSize] = useState({ height: 0, width: 0 })
|
||||
useEffect(() => {
|
||||
setSize({
|
||||
width: window.innerWidth,
|
||||
height: window.innerHeight,
|
||||
})
|
||||
}, [])
|
||||
|
||||
if (width === 0) return
|
||||
|
||||
return (
|
||||
<div className="absolute w-full h-full top-0 left-0 dark:opacity-5 opacity-20 saturate-0 brightness-75 dark:brightness-[1000] -z-20 overflow-hidden flex flex-col marquee-wrapper">
|
||||
{files.map((name) => (
|
||||
<MarqueeItem key={name} name={name} width={width} height={height} />
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function MarqueeItem({ name, width, height }) {
|
||||
const [y] = useState(height * Math.random())
|
||||
const [reset, setReset] = useState(false)
|
||||
const [duration] = useState(clamp(Math.random() * 25, 20, 25))
|
||||
const offset = Math.random() * width
|
||||
useEffect(() => {
|
||||
const timeout =
|
||||
setTimeout(() => {
|
||||
setReset(true)
|
||||
}, (1000 * (width - offset)) / duration) - 2000
|
||||
return () => clearTimeout(timeout)
|
||||
}, [duration, width, offset])
|
||||
return (
|
||||
<motion.span
|
||||
key={name + reset}
|
||||
className="absolute flex items-center justify-center"
|
||||
initial={{ x: reset ? 0 : offset, y }}
|
||||
animate={{ x: width }}
|
||||
transition={{
|
||||
repeat: Infinity,
|
||||
duration: reset ? duration : (width - offset) / duration,
|
||||
ease: "linear",
|
||||
}}
|
||||
>
|
||||
<motion.img
|
||||
src={`/img/providers/${name}`}
|
||||
alt={name}
|
||||
className="relative w-12 drop-shadow-xl"
|
||||
initial={{ opacity: 0, scale: 0.5 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
transition={{
|
||||
delay: reset ? 0 : Math.random() * 5,
|
||||
duration: 1,
|
||||
type: "spring",
|
||||
|
||||
stiffness: 150,
|
||||
}}
|
||||
/>
|
||||
</motion.span>
|
||||
)
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
export default function Triangle({ className }) {
|
||||
return (
|
||||
<svg
|
||||
id="triangle"
|
||||
viewBox="0 0 445 379"
|
||||
className={className}
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<style jsx>
|
||||
{`
|
||||
@media (prefers-color-scheme: light) {
|
||||
#triangle-0 {
|
||||
fill: #000;
|
||||
}
|
||||
#triangle-1 {
|
||||
fill: #ff4400;
|
||||
}
|
||||
#triangle-2 {
|
||||
fill: #bb44cc;
|
||||
}
|
||||
#triangle-3 {
|
||||
fill: #44bbcc;
|
||||
}
|
||||
}
|
||||
`}
|
||||
</style>
|
||||
<path
|
||||
id="triangle-0"
|
||||
d="M334.033 238.33L222.692 46.7201L111.352 238.33H334.033Z"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
id="triangle-1"
|
||||
d="M198.174 1.12812L4.62255 51.2473C1.37638 52.0878 -0.550786 55.4258 0.344333 58.6574L53.7157 251.338C55.1362 256.466 62.0336 257.344 64.6942 252.736L204.874 9.93656C207.535 5.32834 203.325 -0.205751 198.174 1.12812Z"
|
||||
fill="url(#triangle-1-gradient)"
|
||||
/>
|
||||
<path
|
||||
id="triangle-2"
|
||||
d="M246.294 1.12825L439.846 51.2473C443.092 52.0879 445.019 55.4259 444.124 58.6574L390.753 251.338C389.332 256.466 382.435 257.344 379.774 252.736L239.594 9.93665C236.933 5.32844 241.143 -0.205634 246.294 1.12825Z"
|
||||
fill="url(#triangle-2-gradient)"
|
||||
/>
|
||||
<path
|
||||
id="triangle-3"
|
||||
d="M361.388 286.577L225.585 377.959C223.559 379.322 220.91 379.322 218.885 377.959L83.0814 286.577C78.1672 283.27 80.5079 275.599 86.4311 275.599H358.039C363.962 275.599 366.303 283.27 361.388 286.577Z"
|
||||
fill="url(#triangle-3-gradient)"
|
||||
/>
|
||||
<defs>
|
||||
<linearGradient
|
||||
id="triangle-1-gradient"
|
||||
x1="-1.28386"
|
||||
y1="52.7769"
|
||||
x2="134.785"
|
||||
y2="131.336"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stopColor="#992900" />
|
||||
<stop offset="1" stopColor="#FF4400" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="triangle-2-gradient"
|
||||
x1="445.753"
|
||||
y1="52.7769"
|
||||
x2="309.684"
|
||||
y2="131.336"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stopColor="#6D2178" />
|
||||
<stop offset="1" stopColor="#BB44CC" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="triangle-3-gradient"
|
||||
x1="222.236"
|
||||
y1="380.213"
|
||||
x2="222.236"
|
||||
y2="275.599"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stopColor="#1B5B64" />
|
||||
<stop offset="1" stopColor="#44BBCC" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
5
docs/docs/concepts/_category_.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"label": "Concepts",
|
||||
"collapsible": true,
|
||||
"collapsed": true
|
||||
}
|
||||
@@ -174,7 +174,7 @@ If you are deploying directly to a particular cloud platform you may also want t
|
||||
|
||||
## Security
|
||||
|
||||
Parts of this section has been moved to its [own page](/getting-started/security).
|
||||
Parts of this section has been moved to its [own page](/security).
|
||||
|
||||
<details>
|
||||
<summary>
|
||||
@@ -2,16 +2,14 @@
|
||||
title: How OAuth works
|
||||
---
|
||||
|
||||
import { Callout } from 'nextra-theme-docs'
|
||||
|
||||
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)
|
||||
|
||||
<Callout>
|
||||
:::note
|
||||
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.
|
||||
</Callout>
|
||||
:::
|
||||
|
||||
Without going into too much detail, the OAuth flow generally has 6 parts:
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
---
|
||||
title: Contributors
|
||||
displayed_sidebar: null
|
||||
---
|
||||
|
||||
## Core team
|
||||
|
||||
Without these people, the project could not have become one of the most used authentication libraries in its category.
|
||||
Without these people, the project could not have become one of the most used authentication library in its category.
|
||||
|
||||
- [Balázs Orbán](https://github.com/balazsorban44) - **Lead Maintainer**
|
||||
- [Thang Vu](https://github.com/ThangHuuVu) - Maintainer (Core)
|
||||
@@ -9,7 +14,7 @@ Without these people, the project could not have become one of the most used aut
|
||||
|
||||
## Special thanks
|
||||
|
||||
Special thanks to Lori Karikari for creating most of the original provider configurations, to Fredrik Pettersen for creating the original Prisma Adapter, to Gerald Nolan for adding support for Sign in with Apple, and to Jefferson Bledsoe for working on the original testing automation.
|
||||
Special thanks to Lori Karikari for creating most of the original provider configurations to Fredrik Pettersen for creating the original Prisma Adapter, to Gerald Nolan for adding support for Sign in with Apple, and to Jefferson Bledsoe for working on original testing automations.
|
||||
|
||||
- [Lori Karikari](https://github.com/LoriKarikari)
|
||||
- [Fredrik Pettersen](https://github.com/Fumler)
|
||||
@@ -20,7 +25,7 @@ Special thanks to Lori Karikari for creating most of the original provider confi
|
||||
|
||||
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 helped shape Auth.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
|
||||
|
||||
@@ -30,12 +35,8 @@ 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 2022, NextAuth.js was rebranded to Auth.js and became framework/runtime agnostic. The core library `@auth/core` was written by <a href="https://twitter.com/balazsorban44">Balázs Orbán</a>
|
||||
|
||||
- In 2023 // TODO: 👀🤫
|
||||
- In 2021, efforts have started to move Auth.js to other frameworks and to support as many databases and providers as possible.
|
||||
5
docs/docs/getting-started/_category_.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"label": "Getting Started",
|
||||
"collapsible": true,
|
||||
"collapsed": true
|
||||
}
|
||||
@@ -1,9 +1,7 @@
|
||||
---
|
||||
title: Credentials Authentication
|
||||
title: Credentials authentication
|
||||
---
|
||||
|
||||
import { Callout } from 'nextra-theme-docs'
|
||||
|
||||
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.
|
||||
@@ -12,9 +10,9 @@ In case you already have an authentication service, you can use the Credentials
|
||||
|
||||
For this tutorial, we're going to use [Auth.js example app](https://github.com/nextauthjs/next-auth-example) as a base.
|
||||
|
||||
<Callout type="warning">
|
||||
:::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.
|
||||
</Callout>
|
||||
:::
|
||||
|
||||
Integrating the Credentials Provider is as simple as initializing it in the Auth.js configuration file:
|
||||
|
||||
@@ -47,12 +45,12 @@ export default NextAuth({
|
||||
})
|
||||
```
|
||||
|
||||
<Callout type="info">
|
||||
Check the [Credentials Provider options](/reference/providers/credentials) for further customization
|
||||
</Callout>
|
||||
:::note
|
||||
Check the [Credentials Provider options](/reference/core/providers_credentials) for further customization
|
||||
:::
|
||||
|
||||
Note that we only need to define an `authorize` method that is in charge of receiving the credentials inserted by the user and call the authorization service.
|
||||
|
||||
<Callout type="info">
|
||||
:::info
|
||||
If you're using TypeScript, you can [augment the `User` interface](/getting-started/typescript#module-augmentation) to match the response of your `authorize` callback, so whenever you read the user in other callbacks (like the `jwt`) the type will match correctly.
|
||||
</Callout>
|
||||
:::
|
||||
18
docs/docs/getting-started/databases.md
Normal file
@@ -0,0 +1,18 @@
|
||||
---
|
||||
title: Databases
|
||||
---
|
||||
|
||||
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** 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 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 Auth.js with other databases using a [custom adapter](/guides/adapters/creating-a-database-adapter).
|
||||
@@ -2,9 +2,6 @@
|
||||
title: Email authentication
|
||||
---
|
||||
|
||||
import { Callout } from "nextra-theme-docs"
|
||||
import Image from "next/image"
|
||||
|
||||
import smtpConfig from "./img/dashboard-smtp.png"
|
||||
import startPageImg from "./img/email-tutorial-start.png"
|
||||
import checkPageImg from "./img/email-tutorial-check.png"
|
||||
@@ -21,12 +18,9 @@ The Email provider can be used in conjunction with (or instead of) one or more O
|
||||
|
||||
On initial sign in, a **Verification Token** is sent to the email address provided. By default this token **is valid for 24 hours**. If the Verification Token is used within that time (i.e. by clicking on the link in the email) an account is created for the user and they are signed in.
|
||||
|
||||
<Callout>
|
||||
The Email Provider can be used with both JSON Web Tokens and database
|
||||
sessions, but you [must configure a database
|
||||
adapter](/guides/adapters/using-a-database-adapter) to use it. It is not
|
||||
possible to enable email sign in without using a database.
|
||||
</Callout>
|
||||
:::tip
|
||||
The Email Provider can be used with both JSON Web Tokens and database sessions, but you [must configure a database adapter](/guides/adapters/using-a-database-adapter) to use it. It is not possible to enable email sign in without using a database.
|
||||
:::
|
||||
|
||||
## 1. Installing `nodemailer`
|
||||
|
||||
@@ -42,14 +36,13 @@ npm install -D nodemailer
|
||||
|
||||
Next we need a [SMTP service](https://sendgrid.com/blog/what-is-an-smtp-server/) which will be in charge of sending emails from our application. There's a number of services available for this, however [here are the ones](http://nodemailer.com/smtp/well-known/) known to work with `nodemailer`.
|
||||
|
||||
<Callout>
|
||||
For this tutorial, we're going to be using [Sendgrid](https://sendgrid.com/),
|
||||
but any of the services linked above should work the same
|
||||
</Callout>
|
||||
:::info
|
||||
For this tutorial, we're going to be using [Sendgrid](https://sendgrid.com/), but any of the services linked above should work the same
|
||||
:::
|
||||
|
||||
First create an account in and then login to the dashboard, then navigate to "Settings → API Keys" and create an API key:
|
||||
|
||||
<Image src={smtpConfig} />
|
||||
<img src={smtpConfig} />
|
||||
|
||||
Next paste the API in your terminal as so, and run the command:
|
||||
|
||||
@@ -73,17 +66,17 @@ Nice! We're getting there. Now we need to read supply this values as the configu
|
||||
|
||||
```ts title="pages/api/auth/[...nextauth].ts"
|
||||
import NextAuth from "next-auth"
|
||||
import EmailProvider from "next-auth/providers/email"
|
||||
import Email from "next-auth/providers/email"
|
||||
|
||||
export default NextAuth({
|
||||
providers: [
|
||||
Email({
|
||||
server: {
|
||||
host: process.env.EMAIL_SERVER_HOST,
|
||||
port: Number(process.env.EMAIL_SERVER_PORT),
|
||||
host: process.env.SMTP_HOST,
|
||||
port: Number(process.env.SMTP_PORT),
|
||||
auth: {
|
||||
user: process.env.EMAIL_SERVER_USER,
|
||||
pass: process.env.EMAIL_SERVER_PASSWORD,
|
||||
user: process.env.SMTP_USER,
|
||||
pass: process.env.SMTP_PASSWORD,
|
||||
},
|
||||
},
|
||||
from: process.env.EMAIL_FROM,
|
||||
@@ -154,8 +147,8 @@ import EmailProvider from "next-auth/providers/email"
|
||||
|
||||
export default NextAuth({
|
||||
secret: process.env.NEXTAUTH_SECRET,
|
||||
+ adapter: MongoDBAdapter(clientPromise),
|
||||
providers: [
|
||||
+ adapter: MongoDBAdapter(clientPromise),
|
||||
EmailProvider({
|
||||
server: {
|
||||
host: process.env.EMAIL_SERVER_HOST,
|
||||
@@ -179,34 +172,30 @@ Let's start by running a Next.js application with NextAuth, making sure the **Em
|
||||
|
||||
For this tutorial we're going to be using NextAuth example app. Launch the app and click on "Sign in", we're redirected to the Sign In page:
|
||||
|
||||
<Image src={startPageImg} alt="Screenshot of sign in page" />
|
||||
<img src={startPageImg} alt="Screenshot of sign in page" />
|
||||
|
||||
<Callout>
|
||||
You can customize the look and feel of your Sign in page pretty easily with
|
||||
NextAuth. Refer to our [pages guide](/guides/basics/pages) for that!
|
||||
</Callout>
|
||||
:::info
|
||||
You can customize the look and feel of your Sign in page pretty easily with NextAuth. Refer to our [pages guide](/guides/basics/pages) for that!
|
||||
:::
|
||||
|
||||
Then we insert the email address we want to log-in with in the Email credentials section and click on "Sign in with Email".
|
||||
|
||||
NextAuth will then display another page hinting the user to check their email:
|
||||
|
||||
<Image src={checkPageImg} alt="Screenshot of check email page" />
|
||||
<img src={checkPageImg} alt="Screenshot of check email page" />
|
||||
|
||||
Let's now check our email, and look for one sent from NextAuth (check your spam folder just in case):
|
||||
|
||||
<Image src={mailboxImg} alt="Screenshot of mailbox" />
|
||||
<img src={mailboxImg} alt="Screenshot of mailbox" />
|
||||
|
||||
Nice! We got one, coming from the sender specified in the `EMAIL_FROM` environment variable from our configuration above and that's is the sender we verified in Sengrid.
|
||||
Nice! We got one, coming from the sender specified in the `EMAIL_FROM` environment variable from our configuration above and that's is the sender we verified in Sendgrid.
|
||||
|
||||
Click on "Sign in" and a new browser tab will open, you should then land on your application as authenticated!
|
||||
|
||||
<Image src={loggedInImg} alt="Screenshot of logged in" />
|
||||
<img src={loggedInImg} alt="Screenshot of logged in" />
|
||||
|
||||
Easy right? We had to configure Sendgrid and install a database adapter so the user sessions can be saved somewhere, but once done NextAuth will deal with all the user session management for us in a secure way!
|
||||
|
||||
<Callout>
|
||||
A user account (i.e. an entry in the Users table) will not be created for the
|
||||
user until the first time they verify their email address. If an email address
|
||||
is already associated with an account, the user will be signed in to that
|
||||
account when they use the link in the email.
|
||||
</Callout>
|
||||
:::info
|
||||
A user account (i.e. an entry in the Users table) will not be created for the user until the first time they verify their email address. If an email address is already associated with an account, the user will be signed in to that account when they use the link in the email.
|
||||
:::
|
||||
|
Before Width: | Height: | Size: 172 KiB After Width: | Height: | Size: 172 KiB |
|
Before Width: | Height: | Size: 132 KiB After Width: | Height: | Size: 132 KiB |
|
Before Width: | Height: | Size: 175 KiB After Width: | Height: | Size: 175 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 127 KiB After Width: | Height: | Size: 127 KiB |
|
Before Width: | Height: | Size: 157 KiB After Width: | Height: | Size: 157 KiB |
|
Before Width: | Height: | Size: 183 KiB After Width: | Height: | Size: 183 KiB |
|
Before Width: | Height: | Size: 204 KiB After Width: | Height: | Size: 204 KiB |
|
Before Width: | Height: | Size: 172 KiB After Width: | Height: | Size: 172 KiB |
|
Before Width: | Height: | Size: 193 KiB After Width: | Height: | Size: 193 KiB |
|
Before Width: | Height: | Size: 202 KiB After Width: | Height: | Size: 202 KiB |
44
docs/docs/getting-started/introduction.md
Normal file
@@ -0,0 +1,44 @@
|
||||
---
|
||||
title: Introduction
|
||||
sidebar_position: 0
|
||||
---
|
||||
|
||||
## About Auth.js
|
||||
|
||||
Auth.js is a complete open-source authentication solution for web applications. Check out the live demos of Auth.js in action:
|
||||
|
||||
- [Next.js](https://next-auth-example.vercel.app/)
|
||||
- [SvelteKit](https://sveltekit-auth-example.vercel.app/)
|
||||
- [SolidStart](https://auth-solid.vercel.app/)
|
||||
|
||||
Continue to our tutorials to see how to use Auth.js for authentication:
|
||||
|
||||
- [Setup with OAuth](/getting-started/oauth-tutorial)
|
||||
- [Setup with magic links](/getting-started/email-tutorial)
|
||||
- [Integrating with external auth](/getting-started/credentials-tutorial)
|
||||
|
||||
### Battery included
|
||||
|
||||
- Built in support for 60+ popular services (Google, Facebook, Auth0, Apple…)
|
||||
- Built-in email/password-less/magic link
|
||||
- Use with any OAuth 2 or OpenID Connect provider
|
||||
- Use with any username/password store
|
||||
|
||||
### Flexible
|
||||
- Runtime agnostic - run anywhere! Vercel Edge Functions, Node.js, Serverless, etc.
|
||||
- Use with any modern framework! Next.js, SolidStart, SvelteKit, etc.
|
||||
- [Bring Your Own Database](/getting-started/databases) - or none! MySQL, Postgres, MSSQL, MongoDB, etc. Choose database sessions or JWT.
|
||||
|
||||
_Note: Email sign-in requires a database to store single-use verification tokens._
|
||||
|
||||
### Secure by default
|
||||
- Signed, prefixed, server-only cookies
|
||||
- Built-in CSRF protection
|
||||
- Doesn't rely on client-side JavaScript
|
||||
- JWT with JWS / JWE / JWK.
|
||||
|
||||
## Credits
|
||||
|
||||
Auth.js is an open-source project that is only possible [thanks to contributors](/contributors).
|
||||
|
||||
To financially support the development of Auth.js, you can check our [OpenCollective](https://opencollective.com/nextauth) page. We appreciate your support 💚.
|
||||
369
docs/docs/getting-started/oauth-tutorial.mdx
Normal file
@@ -0,0 +1,369 @@
|
||||
---
|
||||
title: OAuth authentication
|
||||
---
|
||||
|
||||
import creatingOauthAppImg from "./img/getting-started-creating-oauth-app.png"
|
||||
import addingCallbackUrlImg from "./img/getting-started-oauth-callback-url.png"
|
||||
import gettingClientIdSecretImg from "./img/getting-started-oauth-clientid-secret.png"
|
||||
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"
|
||||
import Tabs from "@theme/Tabs"
|
||||
import TabItem from "@theme/TabItem"
|
||||
|
||||
The goal of Auth.js is that you can add authentication easily to your project with just a few lines of code.
|
||||
|
||||
The fastest way to set up Auth.js is with an [OAuth](/concepts/oauth) provider. In this tutorial, we'll be setting Auth.js in a web application to be able to log in with **GitHub**.
|
||||
|
||||
:::info
|
||||
Auth.js comes with a list of [built-in providers](/reference/providers/oauth-builtin) (Google, Facebook, Twitter, etc.). You can also integrate it with your OAuth service by [building a custom provider](/guides/providers/custom-provider).
|
||||
:::
|
||||
|
||||
## 1. Configuring Auth.js
|
||||
|
||||
To add Auth.js to your project:
|
||||
|
||||
<Tabs groupId="frameworks" queryString>
|
||||
<TabItem value="next" label="Next.js" default>
|
||||
|
||||
### Prerequisites
|
||||
|
||||
This tutorial assumes you have a Next.js application set up. If you don't, you can follow the [Next.js tutorial](https://nextjs.org/learn/basics/create-nextjs-app) to get started.
|
||||
|
||||
### Installing NextAuth.js
|
||||
|
||||
```bash npm2yarn
|
||||
npm install next-auth
|
||||
```
|
||||
|
||||
:::info
|
||||
We are working on a new `@auth/nextjs` package that will make it easier to set up Auth.js with Next.js. Stay tuned! For now, you can use the `next-auth` package.
|
||||
:::
|
||||
|
||||
### Creating the server config
|
||||
|
||||
Create the following [API route](https://nextjs.org/docs/api-routes/dynamic-api-routes#catch-all-api-routes) file. This route contains the necessary configuration for NextAuth.js, as well as the dynamic route handler:
|
||||
|
||||
```ts title="pages/api/auth/[...nextauth].ts"
|
||||
import NextAuth from "next-auth"
|
||||
import GithubProvider from "next-auth/providers/github"
|
||||
|
||||
export default NextAuth({
|
||||
providers: [
|
||||
GithubProvider({
|
||||
clientId: process.env.GITHUB_ID,
|
||||
clientSecret: process.env.GITHUB_SECRET,
|
||||
}),
|
||||
],
|
||||
})
|
||||
```
|
||||
|
||||
:::info
|
||||
|
||||
Behind the scenes, this creates all the relevant OAuth API routes within `/api/auth/*` so that auth API requests to:
|
||||
|
||||
- [GET `/api/auth/signin`](https://authjs.dev/reference/rest-api#get--apiauthsignin)
|
||||
- [POST `/api/auth/signin/:provider`](https://authjs.dev/reference/rest-api#post--apiauthsigninprovider)
|
||||
- [GET/POST `/api/auth/callback/:provider`](https://authjs.dev/reference/rest-api#get--post--apiauthcallbackprovider)
|
||||
- [GET `/api/auth/signout`](https://authjs.dev/reference/rest-api#get--apiauthsignout)
|
||||
- [POST `/api/auth/signout`](https://authjs.dev/reference/rest-api#post--apiauthsignout)
|
||||
- [GET `/api/auth/session`](https://authjs.dev/reference/rest-api#get--apiauthsession)
|
||||
- [GET `/api/auth/csrf`](https://authjs.dev/reference/rest-api#get--apiauthcsrf)
|
||||
- [GET `/api/auth/providers`](https://authjs.dev/reference/rest-api#get--apiauthproviders)
|
||||
|
||||
can be handled by NextAuth.js. In this way, NextAuth.js stays in charge of the whole application's authentication request/response flow.
|
||||
|
||||
NextAuth.js is fully customizable - [our guides section](/guides/overview) teaches you how to set it up to handle auth in different ways. All the possible configuration options are [listed here](/reference/configuration/auth-config).
|
||||
:::
|
||||
|
||||
### Adding environment variables
|
||||
|
||||
You may notice we are using environment variables in the code example above. We take the value of `GITHUB_ID` and `GITHUB_SECRET` from the GitHub Developer OAuth Portal. See [Configuring OAuth Provider](/getting-started/oauth-tutorial#2-configuring-oauth-provider) section on how to get those.
|
||||
|
||||
In your project root, create a `.env.local` file and add the `NEXTAUTH_SECRET` environment variable:
|
||||
|
||||
```title=".env.local"
|
||||
NEXTAUTH_SECRET="This is an example"
|
||||
```
|
||||
|
||||
`NEXTAUTH_SECRET` is a random string used by the library to encrypt tokens and email verification hashes, and **it's mandatory to keep things secure**! 🔥 🔐 . You can use:
|
||||
|
||||
```
|
||||
$ openssl rand -base64 32
|
||||
```
|
||||
|
||||
or https://generate-secret.vercel.app/32 to generate a random value for it.
|
||||
|
||||
### Exposing the session via `SessionProvider`:
|
||||
|
||||
NextAuth.js provides [`useSession()`](/reference/react/#usesession) - a [React Hooks](https://reactjs.org/docs/hooks-intro.html) to access the session data and status. To use it first you'll need to expose the session context - [`<SessionProvider />`](/reference/react/#sessionprovider) - at the top level of your application:
|
||||
|
||||
```ts title="pages/_app.tsx"
|
||||
import { SessionProvider } from "next-auth/react"
|
||||
|
||||
export default function App({
|
||||
Component,
|
||||
pageProps: { session, ...pageProps },
|
||||
}) {
|
||||
return (
|
||||
<SessionProvider session={session}>
|
||||
<Component {...pageProps} />
|
||||
</SessionProvider>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
Instances of `useSession` (more on it in the next section) will have access to the session data and status. The `<SessionProvider />` also keep the session updated and synced between browser tabs and windows. 💪🏽
|
||||
|
||||
:::tip
|
||||
Check our [client docs](/reference/react/) to learn all the available options for handling sessions on the browser.
|
||||
:::
|
||||
|
||||
### Consuming the session via hooks
|
||||
|
||||
You can use the `useSession` hook from anywhere in your application (E.g. in a header component). Behind the scenes, the hook will connect to the `<SessionProvider />` to read the current user session. Learn more about React Context in the [React docs](https://reactjs.org/docs/context.html).
|
||||
|
||||
```ts title="pages/overview.tsx"
|
||||
import { useSession, signIn, signOut } from "next-auth/react"
|
||||
|
||||
export default function CamperVanPage() {
|
||||
const { data: session, status } = useSession()
|
||||
const userEmail = session?.user?.email
|
||||
|
||||
if (status === "loading") {
|
||||
return <p>Hang on there...</p>
|
||||
}
|
||||
|
||||
if (status === "authenticated") {
|
||||
return (
|
||||
<>
|
||||
<p>Signed in as {userEmail}</p>
|
||||
<button onClick={() => signOut()}>Sign out</button>
|
||||
<img src="https://cdn.pixabay.com/photo/2017/08/11/19/36/vw-2632486_1280.png" />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<p>Not signed in.</p>
|
||||
<button onClick={() => signIn("github")}>Sign in</button>
|
||||
</>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
### Protecting API Routes
|
||||
|
||||
To protect your API Routes (blocking unauthorized access to resources), you can use [`getServerSession()`](/reference/nextjs#getserversession) to know whether a session exists or not:
|
||||
|
||||
```ts title="pages/api/movies/list.ts"
|
||||
import { getServerSession } from "next-auth/next"
|
||||
import { authOptions } from "../auth/[...nextauth]"
|
||||
|
||||
export default async function listMovies(req, res) {
|
||||
const session = await getServerSession(req, res, authOptions)
|
||||
|
||||
if (session) {
|
||||
res.send({
|
||||
movies: [
|
||||
{ title: "Alien vs Predator", id: 1 },
|
||||
{ title: "Reservoir Dogs", id: 2 },
|
||||
],
|
||||
})
|
||||
} else {
|
||||
res.send({
|
||||
error: "You must sign in to view movies.",
|
||||
})
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="sveltekit" label="SvelteKit">
|
||||
TODO: SvelteKit
|
||||
</TabItem>
|
||||
<TabItem value="solidstart" label="SolidStart">
|
||||
TODO: SolidStart
|
||||
</TabItem>
|
||||
<TabItem value="core" label="Vanilla (No Framework)">
|
||||
TODO Core
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## 2. Configuring OAuth Provider
|
||||
|
||||
Ok, we have our app set up with NextAuth.js, however, if you run the app right now, it won't work as we haven't configured our OAuth provider (**GitHub**) yet.
|
||||
|
||||
:::info
|
||||
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 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.
|
||||
|
||||
<img src={creatingOauthAppImg} />
|
||||
|
||||
Log in to **GitHub**, go to [`Settings / Developers / OAuth Apps`](https://github.com/settings/developers) and click "New OAuth App"
|
||||
|
||||
Next, you'll be presented with a screen to add details about your new application. Fill in the required fields, but pay extra attention to the **Authorization Callback URL** one:
|
||||
|
||||
<img src={addingCallbackUrlImg} />
|
||||
|
||||
The callback URL we insert should have the following pattern:
|
||||
|
||||
```
|
||||
[origin]/api/auth/callback/[provider]
|
||||
```
|
||||
|
||||
In this case, given we want to try our authentication working locally on our machine and we're using **GitHub** as our OAuth provider, it'll be:
|
||||
|
||||
<Tabs groupId="frameworks">
|
||||
<TabItem value="next" label="Next.js" default>
|
||||
|
||||
```
|
||||
http://localhost:3000/api/auth/callback/github
|
||||
```
|
||||
|
||||
:::info
|
||||
NextAuth.js will already 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 port `3000` by default. Hence, the origin is `http://localhost:3000`.
|
||||
:::
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="sveltekit" label="SvelteKit">
|
||||
|
||||
```
|
||||
http://localhost:5173/auth/callback/github
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="solidstart" label="SolidStart">
|
||||
TODO SolidStart
|
||||
</TabItem>
|
||||
<TabItem value="core" label="Vanilla (No Framework)">
|
||||
TODO Core
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
:::info
|
||||
The last part of the URL, `[provider]`, is the ID of the provider you're using. In this case, we're using GitHub, so it's `github`. If you're using Google, it'll be `google`, etc... We keep track of the provider IDs internally.
|
||||
The same id is used in the `signIn()` method we saw earlier.
|
||||
:::
|
||||
To register, tap on "Register application" button.
|
||||
|
||||
The next screen shows all the configurations for your newly created OAuth app. For now, we need two things from it - the **Client ID** and **Client Secret**:
|
||||
|
||||
<img src={gettingClientIdSecretImg} />
|
||||
|
||||
The Client ID is always there, a public identifier of your OAuth application within GitHub. Click on the **Generate a new client Secret** button and should be presented with a new string (which is just a randomized string).
|
||||
|
||||
:::warning
|
||||
Keep both your Client ID and Client Secret secure and never expose them to the public or share them with people outside your organization. With them, a malicious actor could hijack your application and cause you and your user serious problems!
|
||||
:::
|
||||
|
||||
Cool! We have finished 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 is 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:
|
||||
|
||||
1. Log in to the provider
|
||||
2. Create create your OAuth application within it
|
||||
3. Set the callback URL
|
||||
4. Get the Client ID and Generate a Client Secret
|
||||
:::
|
||||
|
||||
## 3. Wiring all together
|
||||
|
||||
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.
|
||||
|
||||
Now let's copy both the Client ID and Client Secret and paste them into an environment file in the root of your project like so:
|
||||
|
||||
```title=".env.local"
|
||||
GITHUB_ID=12345
|
||||
GITHUB_SECRET=67890
|
||||
```
|
||||
|
||||
Here is our server configuration file again:
|
||||
|
||||
<Tabs groupId="frameworks">
|
||||
<TabItem value="next" label="Next.js" default>
|
||||
|
||||
```ts title="pages/api/auth/[...nextauth].ts"
|
||||
import NextAuth from "next-auth"
|
||||
import GithubProvider from "next-auth/providers/github"
|
||||
|
||||
export default NextAuth({
|
||||
providers: [
|
||||
GithubProvider({
|
||||
clientId: process.env.GITHUB_ID,
|
||||
clientSecret: process.env.GITHUB_SECRET,
|
||||
}),
|
||||
],
|
||||
})
|
||||
```
|
||||
|
||||
Great! We're now ready to run our application locally. Start the Next.js app by running on your terminal the following command and navigating to [`http://localhost:3000`](http://localhost:3000):
|
||||
|
||||
```
|
||||
$ npm run next dev
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="sveltekit" label="SvelteKit">
|
||||
TODO SvelteKit
|
||||
</TabItem>
|
||||
<TabItem value="solidstart" label="SolidStart">
|
||||
TODO SolidStart
|
||||
</TabItem>
|
||||
<TabItem value="core" label="Vanilla (No Framework)">
|
||||
TODO Core
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
You should see the following page:
|
||||
|
||||
<img src={startAppAndSignInImg} />
|
||||
|
||||
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 session safely in the background:
|
||||
|
||||
<img src={nextAuthUserLoggedIn} />
|
||||
|
||||
Great! We have completed the whole E2E authentication flow setup so that users can log in to our application through GitHub!
|
||||
|
||||
## 4. Deploying to production
|
||||
|
||||
### Configuring different environments
|
||||
|
||||
It's normal to test your application in different environments. Usually, you'll have a development environment (when you run the application locally on your machine), a staging environment (for team members to try the application), and a production environment.
|
||||
|
||||
For each environment, you need to create an OAuth application in your provider respectively, as [we did previously](#2-configuring-oauth-provider), and point the **callback URL** to it.
|
||||
|
||||
For instance, in the previous section, we pointed the callback URL to `http://localhost:3000/api/auth/callback/github` as we wanted to test our application in the development environment.
|
||||
|
||||
If we were to deploy our app to production, we would need to create a new **OAuth App** in GitHub (calling it something like "Van life – prod") and point the **callback URL** to our production domain: `https://example.com/api/auth/callback/github`
|
||||
|
||||
Finally, we would need to point the environment variables we set ( `GITHUB_ID` and `GITHUB_SECRET` ) to the credentials of the OAuth app we want our application to run with.
|
||||
|
||||
### Setting up `NEXTAUTH_URL`
|
||||
|
||||
:::tip
|
||||
Skip this section if you are deploying to Vercel.
|
||||
:::
|
||||
|
||||
When deploying your site, **you need to set** the `NEXTAUTH_URL` environment variable to the canonical URL of your website:
|
||||
|
||||
```
|
||||
NEXTAUTH_URL=https://example.com
|
||||
```
|
||||
|
||||
:::warning
|
||||
In production, this needs to be set as an environment variable on the service you use to deploy your app.
|
||||
|
||||
To set environment variables on Vercel, you can use the [dashboard](https://vercel.com/dashboard) or the `vercel env pull` [command](https://vercel.com/docs/build-step#development-environment-variables).
|
||||
:::
|
||||
|
||||
For more information please check out our [deployment page](/guides/basics/deployment).
|
||||
@@ -2,12 +2,10 @@
|
||||
title: TypeScript
|
||||
---
|
||||
|
||||
import { Callout } from 'nextra-theme-docs'
|
||||
|
||||
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
|
||||
https://github.com/nextauthjs/next-auth-example
|
||||
|
||||
---
|
||||
|
||||
@@ -36,9 +34,9 @@ function MyAdapter() {
|
||||
}
|
||||
```
|
||||
|
||||
<Callout>
|
||||
:::note
|
||||
This will work in code editors with a strong TypeScript integration like VSCode or WebStorm. It might not work if you're using more lightweight editors like VIM or Atom.
|
||||
</Callout>
|
||||
:::
|
||||
|
||||
## Module Augmentation
|
||||
|
||||
@@ -159,6 +157,6 @@ declare module "next-auth/jwt" {
|
||||
|
||||
Contributions of any kind are always welcome, especially for TypeScript. Please keep in mind that we are a small team working on this project in our free time. We will try our best to give support, but if you think you have a solution for a problem, please open a PR!
|
||||
|
||||
<Callout>
|
||||
:::note
|
||||
When contributing to TypeScript, if the actual JavaScript user API does not change in a breaking manner, we reserve the right to push any TypeScript change in a minor release. This ensures that we can keep on a faster release cycle.
|
||||
</Callout>
|
||||
:::
|
||||
612
docs/docs/getting-started/upgrade-to-v4.md
Normal file
@@ -0,0 +1,612 @@
|
||||
---
|
||||
title: Upgrade Guide (v4)
|
||||
---
|
||||
|
||||
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 🚨
|
||||
|
||||
We encourage users to try it out and report any and all issues they come across.
|
||||
:::
|
||||
|
||||
You can upgrade to the new version by running:
|
||||
|
||||
```bash npm2yarn
|
||||
npm install next-auth
|
||||
```
|
||||
|
||||
## `next-auth/jwt`
|
||||
|
||||
We no longer have a default export in `next-auth/jwt`.
|
||||
To comply with this, change the following:
|
||||
|
||||
```diff
|
||||
- import jwt from "next-auth/jwt"
|
||||
+ import { getToken } from "next-auth/jwt"
|
||||
```
|
||||
|
||||
## `next-auth/react`
|
||||
|
||||
We've renamed the client-side import source to `next-auth/react`. To comply with this change, you will simply have to rename anywhere you were using `next-auth/client`.
|
||||
|
||||
For example:
|
||||
|
||||
```diff
|
||||
- import { useSession } from "next-auth/client"
|
||||
+ import { useSession } from "next-auth/react"
|
||||
```
|
||||
|
||||
We've also made the following changes to the names of the exports:
|
||||
|
||||
- `setOptions`: Not exposed anymore, use [`SessionProvider` props](/reference/react/#sessionprovider)
|
||||
- `options`: Not exposed anymore, [use `SessionProvider` props](/reference/react/#sessionprovider)
|
||||
- `session`: Renamed to `getSession`
|
||||
- `providers`: Renamed to `getProviders`
|
||||
- `csrfToken`: Renamed to `getCsrfToken`
|
||||
- `signin`: Renamed to `signIn`
|
||||
- `signout`: Renamed to `signOut`
|
||||
- `Provider`: Renamed to `SessionProvider`
|
||||
|
||||
Introduced in https://github.com/nextauthjs/next-auth/releases/tag/v4.0.0-next.12
|
||||
|
||||
## `SessionProvider`
|
||||
|
||||
Version 4 makes using the `SessionProvider` mandatory. This means that you will have to wrap any part of your application using `useSession` in this provider, if you were not doing so already. The `SessionProvider` has also undergone a few further changes:
|
||||
|
||||
- `Provider` is renamed to `SessionProvider`
|
||||
- The options prop is now flattened as the props of SessionProvider.
|
||||
- `keepAlive` has been renamed to `refetchInterval`.
|
||||
- `clientMaxAge` has been removed in favor of `refetchInterval`, as they overlap in functionality, with the difference that `refetchInterval` will keep re-fetching the session periodically in the background.
|
||||
|
||||
The best practice for wrapping your app in Providers is to do so in your `pages/_app.jsx` file.
|
||||
|
||||
An example use-case with these new changes:
|
||||
|
||||
```jsx
|
||||
import { SessionProvider } from "next-auth/react"
|
||||
|
||||
export default function App({
|
||||
Component,
|
||||
pageProps: { session, ...pageProps },
|
||||
}) {
|
||||
return (
|
||||
// `session` comes from `getServerSideProps` or `getInitialProps`.
|
||||
// Avoids flickering/session loading on first load.
|
||||
<SessionProvider session={session} refetchInterval={5 * 60}>
|
||||
<Component {...pageProps} />
|
||||
</SessionProvider>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
Introduced in https://github.com/nextauthjs/next-auth/releases/tag/v4.0.0-next.12
|
||||
|
||||
## Providers
|
||||
|
||||
Providers now need to be imported individually.
|
||||
|
||||
```diff
|
||||
- import Provider from "next-auth/providers"
|
||||
- Providers.Auth0({...})
|
||||
- Providers.Google({...})
|
||||
+ import Auth0Provider from "next-auth/providers/auth0"
|
||||
+ import GoogleProvider from "next-auth/providers/google"
|
||||
+ Auth0Provider({...})
|
||||
+ GoogleProvider({...})
|
||||
```
|
||||
|
||||
1. The `AzureADB2C` provider has been renamed `AzureAD`.
|
||||
2. The `Basecamp` provider has been removed, see explanation [here](https://github.com/basecamp/api/blob/master/sections/authentication.md#on-authenticating-users-via-oauth).
|
||||
3. The GitHub provider by default now will not request full write access to user profiles. If you need this scope, please add `user` to the scope option manually.
|
||||
|
||||
The following new options are available when defining your Providers in the configuration:
|
||||
|
||||
1. `authorization` (replaces `authorizationUrl`, `authorizationParams`, `scope`)
|
||||
2. `token` replaces (`accessTokenUrl`, `headers`, `params`)
|
||||
3. `userinfo` (replaces `profileUrl`)
|
||||
4. `issuer`(replaces `domain`)
|
||||
|
||||
For more details on their usage, please see [options](/reference/providers/oauth) section of the OAuth Provider documentation.
|
||||
|
||||
When submitting a new OAuth provider to the repository, the `profile` callback is expected to only return these fields from now on: `id`, `name`, `email`, and `image`. If any of these are missing values, they should be set to `null`.
|
||||
|
||||
Also worth noting is that `id` is expected to be returned as a `string` type (For example if your provider returns it as a number, you can cast it by using the `.toString()` method). This makes the returned profile object comply across all providers/accounts/adapters, and hopefully cause less confusion in the future.
|
||||
|
||||
Implemented in: https://github.com/nextauthjs/next-auth/pull/2411
|
||||
Introduced in https://github.com/nextauthjs/next-auth/releases/tag/v4.0.0-next.20
|
||||
|
||||
## `useSession` Hook
|
||||
|
||||
The `useSession` hook has been updated to return an object. This allows you to test states much more cleanly with the new `status` option.
|
||||
|
||||
```diff
|
||||
- const [ session, loading ] = useSession()
|
||||
+ const { data: session, status } = useSession()
|
||||
+ const loading = status === "loading"
|
||||
```
|
||||
|
||||
[Check the docs](/reference/react/#usesession) for the possible values of both `session.status` and `session.data`.
|
||||
|
||||
Introduced in https://github.com/nextauthjs/next-auth/releases/tag/v4.0.0-next.18
|
||||
|
||||
## Named Parameters
|
||||
|
||||
We have changed the arguments to our callbacks to the named parameters pattern. This way you don't have to use dummy `_` placeholders or other tricks.
|
||||
|
||||
### Callbacks
|
||||
|
||||
The signatures for the callback methods now look like this:
|
||||
|
||||
```diff
|
||||
- signIn(user, account, profileOrEmailOrCredentials)
|
||||
+ signIn({ user, account, profile, email, credentials })
|
||||
```
|
||||
|
||||
```diff
|
||||
- redirect(url, baseUrl)
|
||||
+ redirect({ url, baseUrl })
|
||||
```
|
||||
|
||||
```diff
|
||||
- session(session, tokenOrUser)
|
||||
+ session({ session, token, user })
|
||||
```
|
||||
|
||||
```diff
|
||||
- jwt(token, user, account, OAuthProfile, isNewUser)
|
||||
+ jwt({ token, user, account, profile, isNewUser })
|
||||
```
|
||||
|
||||
Introduced in https://github.com/nextauthjs/next-auth/releases/tag/v4.0.0-next.17
|
||||
|
||||
### Events
|
||||
|
||||
Two event signatures have changed to also use the named parameters pattern, `signOut` and `updateUser`.
|
||||
|
||||
```diff
|
||||
// [...nextauth].js
|
||||
...
|
||||
events: {
|
||||
- signOut(tokenOrSession),
|
||||
+ signOut({ token, session }), // token if using JWT, session if DB persisted sessions.
|
||||
- updateUser(user)
|
||||
+ updateUser({ user })
|
||||
}
|
||||
```
|
||||
|
||||
Introduced in https://github.com/nextauthjs/next-auth/releases/tag/v4.0.0-next.20
|
||||
|
||||
## JWT configuration
|
||||
|
||||
We have removed some of the [configuration options](/reference/configuration/auth-config) when using JSON Web Tokens, [here's the PR](https://github.com/nextauthjs/next-auth/pull/3039) for more context.
|
||||
|
||||
```diff
|
||||
export default NextAuth({
|
||||
// ...
|
||||
jwt: {
|
||||
secret,
|
||||
maxAge,
|
||||
- encryptionKey
|
||||
- signingKey
|
||||
- encryptionKey
|
||||
- verificationOptions
|
||||
encode({
|
||||
token
|
||||
secret
|
||||
maxAge
|
||||
- signingKey
|
||||
- signingOptions
|
||||
- encryptionKey
|
||||
- encryptionOptions
|
||||
- encryption
|
||||
}) {},
|
||||
decode({
|
||||
token
|
||||
secret
|
||||
- maxAge
|
||||
- signingKey
|
||||
- verificationKey
|
||||
- verificationOptions
|
||||
- encryptionKey
|
||||
- decryptionKey
|
||||
- decryptionOptions
|
||||
- encryption
|
||||
}) {}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
## Logger API
|
||||
|
||||
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
|
||||
// [...Auth.js]
|
||||
import log from "some-logger-service"
|
||||
...
|
||||
logger: {
|
||||
- error(code, ...message) {},
|
||||
+ error(code, metadata) {},
|
||||
- warn(code, ...message) {},
|
||||
+ warn(code) {}
|
||||
- debug(code, ...message) {}
|
||||
+ debug(code, metadata) {}
|
||||
}
|
||||
```
|
||||
|
||||
Introduced in https://github.com/nextauthjs/next-auth/releases/tag/v4.0.0-next.19
|
||||
|
||||
## `nodemailer`
|
||||
|
||||
Like `typeorm` and `prisma`, [`nodemailer`](https://npmjs.com/package/nodemailer) is no longer included as a dependency by default. If you are using the Email provider you must install it in your project manually, or use any other Email library in the [`sendVerificationRequest`](/guides/providers/email) callback. This reduces bundle size for those not actually using the Email provider. Remember, when using the Email provider, it is mandatory to also use a database adapter due to the fact that verification tokens need to be persisted longer term for the magic link functionality to work.
|
||||
|
||||
Introduced in https://github.com/nextauthjs/next-auth/releases/tag/v4.0.0-next.2
|
||||
|
||||
## Theme
|
||||
|
||||
We have added some basic customization options to our built-in pages like `signin`, `signout`, etc.
|
||||
|
||||
These can be set under the `theme` configuration key. This used to be a string which only controlled the color scheme option. Now it is an object with the following options:
|
||||
|
||||
```js
|
||||
theme: {
|
||||
colorScheme: "auto", // "auto" | "dark" | "light"
|
||||
brandColor: "", // Hex color value
|
||||
logo: "" // Absolute URL to logo image
|
||||
}
|
||||
```
|
||||
|
||||
The hope is that with some minimal configuration / customization options, users won't immediately feel the need to replace the built-in pages with their own.
|
||||
|
||||
More details and screenshots of the new theme options can be found under [custom pages tutorial](/guides/basics/pages).
|
||||
|
||||
Introduced in https://github.com/nextauthjs/next-auth/pull/2788
|
||||
|
||||
## Session
|
||||
|
||||
The `session.jwt: boolean` option has been renamed to `session.strategy: "jwt" | "database"`. The goal is to make the user's options more intuitive:
|
||||
|
||||
1. No adapter, `strategy: "jwt"`: This is the default. The session is saved in a cookie and never persisted anywhere.
|
||||
2. With Adapter, `strategy: "database"`: If an Adapter is defined, this will be the implicit setting. No user config is needed.
|
||||
3. With Adapter, `strategy: "jwt"`: The user can explicitly instruct `next-auth` to use JWT even if a database is available. This can result in faster lookups in compromise of lowered security. Read more about: https://authjs.dev/concepts/faq#json-web-tokens
|
||||
|
||||
Example:
|
||||
|
||||
```diff
|
||||
session: {
|
||||
- jwt: true,
|
||||
+ strategy: "jwt",
|
||||
}
|
||||
```
|
||||
|
||||
Introduced in https://github.com/nextauthjs/next-auth/pull/3144
|
||||
|
||||
## Adapters
|
||||
|
||||
Most importantly, the core `next-auth` package no longer ships with `typeorm` or any other database adapter by default. This brings the default bundle size down significantly for those not needing to persist user data to a database.
|
||||
|
||||
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 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`.
|
||||
|
||||
The `database` option has been removed, you must now do the following instead:
|
||||
|
||||
```diff
|
||||
// [...nextauth].js
|
||||
import NextAuth from "next-auth"
|
||||
+ import { TypeORMLegacyAdapter } from "@next-auth/typeorm-legacy-adapter"
|
||||
|
||||
...
|
||||
export default NextAuth({
|
||||
- database: "yourconnectionstring",
|
||||
+ adapter: TypeORMLegacyAdapter("yourconnectionstring")
|
||||
})
|
||||
```
|
||||
|
||||
2. The `prisma-legacy` adapter has been removed, please use the [`@next-auth/prisma-adapter`](https://npmjs.com/package/@next-auth/prisma-adapter) instead.
|
||||
|
||||
3. The `typeorm-legacy` adapter has been upgraded to use the newer adapter API, but has retained the `typeorm-legacy` name. We aim to migrate this to individual lighter weight adapters for each database type in the future, or switch out `typeorm`.
|
||||
|
||||
4. MongoDB has been moved to its own adapter under `@next-auth/mongodb-adapter`. See the [MongoDB Adapter docs](/reference/adapters/mongodb).
|
||||
|
||||
Introduced in https://github.com/nextauthjs/next-auth/releases/tag/v4.0.0-next.8 and https://github.com/nextauthjs/next-auth/pull/2361
|
||||
|
||||
### Adapter API
|
||||
|
||||
**This does not require any changes from the user - these are adapter specific changes only**
|
||||
|
||||
The Adapter API has been rewritten and significantly simplified in NextAuth v4. The adapters now have less work to do as some functionality has been migrated to the core of NextAuth, like hashing the [verification token](/reference/adapters/models/#verification-token).
|
||||
|
||||
If you are an adapter maintainer or are interested in writing your own adapter, you can find more information about this change in https://github.com/nextauthjs/next-auth/pull/2361 and release https://github.com/nextauthjs/next-auth/releases/tag/v4.0.0-next.22.
|
||||
|
||||
### Schema changes
|
||||
|
||||
The way we save data with adapters have slightly changed. With the new Adapter API, we wanted to make it easier to extend your database with additional fields. For example if your User needs an extra `phone` field, it should be enough to add that to your database's schema, and no changes will be necessary in your adapter.
|
||||
|
||||
- `created_at`/`createdAt` and `updated_at`/`updatedAt` fields are removed from all Models.
|
||||
- `user_id`/`userId` consistently named `userId`.
|
||||
- `compound_id`/`compoundId` is removed from Account.
|
||||
- `access_token`/`accessToken` is removed from Session.
|
||||
- `email_verified`/`emailVerified` on User is consistently named `emailVerified`.
|
||||
- `provider_id`/`providerId` renamed to `provider` on Account
|
||||
- `provider_type`/`providerType` renamed to `type` on Account
|
||||
- `provider_account_id`/`providerAccountId` on Account is consistently named `providerAccountId`
|
||||
- `access_token_expires`/`accessTokenExpires` on Account renamed to `expires_at`
|
||||
- New fields on Account: `token_type`, `scope`, `id_token`, `session_state`
|
||||
- `verification_requests` table has been renamed to `verification_tokens`
|
||||
|
||||
<!-- REVIEW: Would something like this below be helpful? -->
|
||||
<details>
|
||||
<summary>
|
||||
See the changes
|
||||
</summary>
|
||||
<pre>
|
||||
|
||||
```diff
|
||||
User {
|
||||
id
|
||||
name
|
||||
email
|
||||
- emailVerified
|
||||
+ email_verified
|
||||
image
|
||||
- created_at
|
||||
- updated_at
|
||||
}
|
||||
|
||||
Account {
|
||||
id
|
||||
- compound_id
|
||||
- user_id
|
||||
+ userId
|
||||
- provider_type
|
||||
+ type
|
||||
- provider_id
|
||||
+ provider
|
||||
- provider_account_id
|
||||
+ providerAccountId
|
||||
refresh_token
|
||||
access_token
|
||||
- access_token_expires
|
||||
+ expires_in
|
||||
+ expires_at
|
||||
+ token_type
|
||||
+ scope
|
||||
+ id_token
|
||||
+ session_state
|
||||
- created_at
|
||||
- updated_at
|
||||
}
|
||||
|
||||
Session {
|
||||
id
|
||||
userId
|
||||
expires
|
||||
sessionToken
|
||||
- access_token
|
||||
- created_at
|
||||
- updated_at
|
||||
}
|
||||
|
||||
VerificationToken {
|
||||
id
|
||||
token
|
||||
expires
|
||||
identifier
|
||||
- created_at
|
||||
- updated_at
|
||||
}
|
||||
```
|
||||
|
||||
</pre>
|
||||
</details>
|
||||
|
||||
For more info, see the [Models page](/reference/adapters/models).
|
||||
|
||||
### Database migration
|
||||
|
||||
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.
|
||||
|
||||
#### MySQL
|
||||
|
||||
```sql
|
||||
/* ACCOUNT */
|
||||
ALTER TABLE accounts
|
||||
CHANGE "access_token_expires" "expires_at" int
|
||||
CHANGE "user_id" "userId" varchar(255)
|
||||
ADD CONSTRAINT fk_user_id FOREIGN KEY (userId) REFERENCES users(id)
|
||||
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 Auth.js to function, but can be kept if you want */
|
||||
DROP COLUMN "created_at"
|
||||
DROP COLUMN "updated_at"
|
||||
|
||||
ADD COLUMN "token_type" varchar(255) NULL
|
||||
ADD COLUMN "scope" varchar(255) NULL
|
||||
ADD COLUMN "id_token" varchar(255) NULL
|
||||
ADD COLUMN "session_state" varchar(255) NULL
|
||||
|
||||
/* Note: These are only needed if you're going to be using the old Twitter OAuth 1.0 provider. */
|
||||
ADD COLUMN "oauth_token_secret" varchar(255) NULL
|
||||
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 Auth.js to function, but can be kept if you want */
|
||||
DROP COLUMN "created_at"
|
||||
DROP COLUMN "updated_at"
|
||||
|
||||
/* SESSION */
|
||||
ALTER TABLE sessions
|
||||
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 Auth.js to function, but can be kept if you want */
|
||||
DROP COLUMN "created_at"
|
||||
DROP COLUMN "updated_at"
|
||||
|
||||
/* VERIFICATION REQUESTS */
|
||||
ALTER TABLE verification_requests RENAME verification_tokens
|
||||
ALTER TABLE verification_tokens
|
||||
DROP COLUMN id
|
||||
/* 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"
|
||||
```
|
||||
|
||||
#### Postgres
|
||||
|
||||
```sql
|
||||
/* ACCOUNT */
|
||||
ALTER TABLE accounts RENAME COLUMN "user_id" TO "userId";
|
||||
ALTER TABLE accounts RENAME COLUMN "provider_id" TO "provider";
|
||||
ALTER TABLE accounts RENAME COLUMN "provider_account_id" TO "providerAccountId";
|
||||
ALTER TABLE accounts RENAME COLUMN "access_token_expires" TO "expires_at";
|
||||
ALTER TABLE accounts RENAME COLUMN "provider_type" TO "type";
|
||||
|
||||
/* Do conversion of TIMESTAMPTZ to BIGINT */
|
||||
ALTER TABLE accounts ALTER COLUMN "expires_at" TYPE TEXT USING CAST(extract(epoch FROM "expires_at") AS BIGINT)*1000;
|
||||
|
||||
/* Keep id as SERIAL with autoincrement when using ORM. Using new v4 uuid format won't work because of incompatibility */
|
||||
/* ALTER TABLE accounts ALTER COLUMN "id" TYPE TEXT; */
|
||||
/* ALTER TABLE accounts ALTER COLUMN "userId" TYPE TEXT; */
|
||||
ALTER TABLE accounts ALTER COLUMN "type" TYPE TEXT;
|
||||
ALTER TABLE accounts ALTER COLUMN "provider" TYPE TEXT;
|
||||
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 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";
|
||||
|
||||
ALTER TABLE accounts
|
||||
ADD COLUMN IF NOT EXISTS "token_type" TEXT NULL,
|
||||
ADD COLUMN IF NOT EXISTS "scope" TEXT NULL,
|
||||
ADD COLUMN IF NOT EXISTS "id_token" TEXT NULL,
|
||||
ADD COLUMN IF NOT EXISTS "session_state" TEXT NULL;
|
||||
/* Note: These are only needed if you're going to be using the old Twitter OAuth 1.0 provider. */
|
||||
/* ALTER TABLE accounts
|
||||
ADD COLUMN IF NOT EXISTS "oauth_token_secret" TEXT NULL,
|
||||
ADD COLUMN IF NOT EXISTS "oauth_token" TEXT NULL; */
|
||||
|
||||
/* USER */
|
||||
ALTER TABLE users RENAME COLUMN "email_verified" TO "emailVerified";
|
||||
|
||||
/* Keep id as SERIAL with autoincrement when using ORM. Using new v4 uuid format won't work because of incompatibility */
|
||||
/* ALTER TABLE users ALTER COLUMN "id" TYPE TEXT; */
|
||||
ALTER TABLE users ALTER COLUMN "name" TYPE TEXT;
|
||||
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 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";
|
||||
|
||||
/* SESSION */
|
||||
ALTER TABLE sessions RENAME COLUMN "session_token" TO "sessionToken";
|
||||
ALTER TABLE sessions RENAME COLUMN "user_id" TO "userId";
|
||||
|
||||
/* Keep id as SERIAL with autoincrement when using ORM. Using new v4 uuid format won't work because of incompatibility */
|
||||
/* ALTER TABLE sessions ALTER COLUMN "id" TYPE TEXT; */
|
||||
/* ALTER TABLE sessions ALTER COLUMN "userId" TYPE TEXT; */
|
||||
ALTER TABLE sessions ALTER COLUMN "sessionToken" TYPE TEXT;
|
||||
ALTER TABLE sessions ADD CONSTRAINT fk_user_id FOREIGN KEY ("userId") REFERENCES users(id);
|
||||
/* 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 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";
|
||||
|
||||
/* VERIFICATION REQUESTS */
|
||||
ALTER TABLE verification_requests RENAME TO verification_tokens;
|
||||
/* Keep id as ORM needs it */
|
||||
/* ALTER TABLE verification_tokens DROP COLUMN IF EXISTS id; */
|
||||
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 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";
|
||||
```
|
||||
|
||||
#### MongoDB
|
||||
|
||||
MongoDB is a document database and as such new fields will be automatically populated. You do, however, need to update the names of existing fields which are going to be reused.
|
||||
|
||||
```mongo
|
||||
db.getCollection('accounts').updateMany({}, {
|
||||
$rename: {
|
||||
"provider_id": "provider",
|
||||
"provider_account_id": "providerAccountId",
|
||||
"user_id": "userId",
|
||||
"access_token_expires": "expires_at"
|
||||
}
|
||||
})
|
||||
db.getCollection('users').updateMany({}, {
|
||||
$rename: {
|
||||
"email_verified": "emailVerified"
|
||||
}
|
||||
})
|
||||
db.getCollection('sessions').updateMany({}, {
|
||||
$rename: {
|
||||
"session_token": "sessionToken",
|
||||
"user_id": "userId"
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
## Missing `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:
|
||||
|
||||
```bash
|
||||
$ openssl rand -base64 32
|
||||
```
|
||||
|
||||
Therefore, your Auth.js config should look something like this:
|
||||
|
||||
```javascript title="/pages/api/auth/[...nextauth].js"
|
||||
...
|
||||
export default NextAuth({
|
||||
...
|
||||
providers: [...],
|
||||
secret: "LlKq6ZtYbr+hTC073mAmAh9/h2HwMfsFo4hrfCx5mLg=",
|
||||
...
|
||||
})
|
||||
```
|
||||
|
||||
Introduced in https://github.com/nextauthjs/next-auth/issues/3143
|
||||
|
||||
## Session `strategy`
|
||||
|
||||
We have always supported two different session strategies. The first being our most popular and default strategy - the JWT based one. The second is the database adapter persisted session strategy. Both have their advantages/disadvantages, you can learn more about them on the [FAQ](/concepts/faq) page.
|
||||
|
||||
Previously, the way you configured this was through the `jwt: boolean` flag in the `session` option. The names `session` and `jwt` might have been a bit overused in the options, and so for a clearer message, we renamed this option to `strategy: "jwt" | "database"`, it is still in the `session` object. This will hopefully better indicate the purpose of this option as well as make very explicit which type of session you are going to use.
|
||||
|
||||
See the [`session` option docs](/reference/configuration/auth-config#session) for more details.
|
||||
|
||||
Introduced in https://github.com/nextauthjs/next-auth/pull/3144
|
||||
|
||||
## Summary
|
||||
|
||||
We hope this migration goes smoothly for each and every one of you! If you have any questions or get stuck anywhere, feel free to create [a new issue](https://github.com/nextauthjs/next-auth/issues/new) on GitHub.
|
||||
5
docs/docs/guides/adapters/_category_.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"label": "Adapters",
|
||||
"collapsible": true,
|
||||
"collapsed": true
|
||||
}
|
||||
@@ -1,15 +1,13 @@
|
||||
---
|
||||
title: Using a Database Adapter
|
||||
title: Using a database adapter
|
||||
---
|
||||
|
||||
import { Callout } from 'nextra-theme-docs'
|
||||
|
||||
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).
|
||||
|
||||
<Callout>
|
||||
:::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).
|
||||
</Callout>
|
||||
:::
|
||||
|
||||
We have a list of official adapters that are distributed as their own packages under the `@next-auth/{name}-adapter` namespace. Their source code is available in their various adapters package directories at [`nextauthjs/next-auth`](https://github.com/nextauthjs/next-auth/tree/main/packages):
|
||||
|
||||
- [All available adapters](/reference/adapters/overview)
|
||||
- [All available adapters](/reference/adapters)
|
||||
5
docs/docs/guides/basics/_category_.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"label": "Basics",
|
||||
"collapsible": true,
|
||||
"collapsed": false
|
||||
}
|
||||
@@ -2,18 +2,13 @@
|
||||
title: Callbacks
|
||||
---
|
||||
|
||||
import { Callout } from "nextra-theme-docs"
|
||||
|
||||
Callbacks are **asynchronous** functions you can use to control what happens when an action is performed.
|
||||
|
||||
Callbacks are extremely powerful, especially in scenarios involving JSON Web Tokens as they allow you to implement access controls without a database and to integrate with external databases or APIs.
|
||||
|
||||
<Callout>
|
||||
If you want to pass data such as an Access Token or User ID to the browser
|
||||
when using JSON Web Tokens, you can persist the data in the token when the
|
||||
`jwt` callback is called, then pass the data through to the browser in the
|
||||
`session` callback.
|
||||
</Callout>
|
||||
:::tip
|
||||
If you want to pass data such as an Access Token or User ID to the browser when using JSON Web Tokens, you can persist the data in the token when the `jwt` callback is called, then pass the data through to the browser in the `session` callback.
|
||||
:::
|
||||
|
||||
You can specify a handler for any of the callbacks below.
|
||||
|
||||
@@ -64,19 +59,17 @@ 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.
|
||||
|
||||
<Callout>
|
||||
:::note
|
||||
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 Auth.js without a database, the user object will always be a prototype user object, with information extracted from the profile.
|
||||
:::
|
||||
|
||||
</Callout>
|
||||
|
||||
<Callout>
|
||||
:::note
|
||||
Redirects returned by this callback cancel the authentication flow. Only redirect to error pages that, for example, tell the user why they're not allowed to sign in.
|
||||
|
||||
To redirect to a page after a successful sign in, please use [the `callbackUrl` option](/reference/utilities/#specifying-a-callbackurl) or [the redirect callback](/reference/configuration/auth-config#callbacks).
|
||||
|
||||
</Callout>
|
||||
:::
|
||||
|
||||
## Redirect callback
|
||||
|
||||
@@ -98,9 +91,9 @@ callbacks: {
|
||||
}
|
||||
```
|
||||
|
||||
<Callout>
|
||||
The redirect callback may be invoked more than once in the same flow.
|
||||
</Callout>
|
||||
:::note
|
||||
The redirect callback may be invoked more than once in the same flow.
|
||||
:::
|
||||
|
||||
## JWT callback
|
||||
|
||||
@@ -126,13 +119,9 @@ callbacks: {
|
||||
}
|
||||
```
|
||||
|
||||
<Callout>
|
||||
Use an if branch to check for the existence of parameters (apart from
|
||||
`token`). If they exist, this means that the callback is being invoked for the
|
||||
first time (i.e. the user is being signed in). This is a good place to persist
|
||||
additional data like an `access_token` in the JWT. Subsequent invocations will
|
||||
only contain the `token` parameter.
|
||||
</Callout>
|
||||
:::tip
|
||||
Use an if branch to check for the existence of parameters (apart from `token`). If they exist, this means that the callback is being invoked for the first time (i.e. the user is being signed in). This is a good place to persist additional data like an `access_token` in the JWT. Subsequent invocations will only contain the `token` parameter.
|
||||
:::
|
||||
|
||||
## Session callback
|
||||
|
||||
@@ -153,18 +142,15 @@ callbacks: {
|
||||
}
|
||||
```
|
||||
|
||||
<Callout>
|
||||
When using JSON Web Tokens the `jwt()` callback is invoked before the
|
||||
`session()` callback, so anything you add to the JSON Web Token will be
|
||||
immediately available in the session callback, like for example an
|
||||
`access_token` from a provider.
|
||||
</Callout>
|
||||
:::tip
|
||||
When using JSON Web Tokens the `jwt()` callback is invoked before the `session()` callback, so anything you add to the
|
||||
JSON Web Token will be immediately available in the session callback, like for example an `access_token` from a provider.
|
||||
:::
|
||||
|
||||
<Callout type="warning">
|
||||
:::warning
|
||||
The session object is not persisted server side, even when using database sessions - only data such as the session token, the user, and the expiry time is stored in the session table.
|
||||
|
||||
If you need to persist session data server side, you can use the `accessToken` returned for the session as a key - and connect to the database in the `session()` callback to access it. Session `accessToken` values do not rotate and are valid as long as the session is valid.
|
||||
|
||||
If using JSON Web Tokens instead of database sessions, you should use the User ID or a unique key stored in the token (you will need to generate a key for this yourself on sign in, as access tokens for sessions are not generated when using JSON Web Tokens).
|
||||
|
||||
</Callout>
|
||||
:::
|
||||
@@ -2,15 +2,13 @@
|
||||
title: Events
|
||||
---
|
||||
|
||||
import { Callout } from 'nextra-theme-docs'
|
||||
|
||||
Events are asynchronous functions that do not return a response, they are useful for audit logs / reporting or handling any other side-effects.
|
||||
|
||||
You can specify a handler for any of these events below, for debugging or for an audit log.
|
||||
|
||||
<Callout>
|
||||
:::note
|
||||
The execution of your authentication API will be blocked by an `await` on your event handler. If your event handler starts any burdensome work it should not block its own promise on that work.
|
||||
</Callout>
|
||||
:::
|
||||
|
||||
## Events
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
title: Custom Initialization
|
||||
---
|
||||
|
||||
import { Callout } from 'nextra-theme-docs'
|
||||
|
||||
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 Auth.js that every API request beginning with `/api/auth/*` should be handled by the code written in the `[...nextauth]` file.
|
||||
@@ -48,15 +46,15 @@ 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.
|
||||
|
||||
<Callout>
|
||||
:::tip
|
||||
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"`
|
||||
</Callout>
|
||||
:::
|
||||
|
||||
<Callout>
|
||||
:::note
|
||||
`NextAuth` will implicitly close the response (by calling `res.end`, `res.send` or similar), so you should not run code **after** `NextAuth` in the function body. Using `return NextAuth` makes sure you don't forget that.
|
||||
</Callout>
|
||||
:::
|
||||
|
||||
Any variable you create this way will be available in the `NextAuth` options as well, since they are in the same scope.
|
||||
|
||||
@@ -119,6 +117,6 @@ For more details on all available actions and which methods are supported, pleas
|
||||
|
||||
This way of initializing `NextAuth` is very powerful, but should be used sparingly.
|
||||
|
||||
<Callout type="warning">
|
||||
:::warning
|
||||
Changing parts of the request that is essential to `NextAuth` to do it's job - like messing with the [default cookies](/reference/configuration/auth-config#cookies) - can have unforeseen consequences, and have the potential to introduce security holes if done incorrectly. Only change those if you understand consequences.
|
||||
</Callout>
|
||||
:::
|
||||
@@ -3,11 +3,9 @@ title: Override JWT `encode` and `decode` methods
|
||||
sidebar_label: Custom JWT encoding
|
||||
---
|
||||
|
||||
import { Callout } from "nextra-theme-docs"
|
||||
|
||||
<Callout type="warning">
|
||||
:::warning
|
||||
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)
|
||||
</Callout>
|
||||
:::
|
||||
|
||||
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.
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
title: Pages
|
||||
---
|
||||
|
||||
import { Callout } from 'nextra-theme-docs'
|
||||
|
||||
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 Auth.js.
|
||||
@@ -22,9 +20,9 @@ To add a custom login page, you can use the `pages` option:
|
||||
...
|
||||
```
|
||||
|
||||
<Callout>
|
||||
:::note
|
||||
When using this configuration, ensure that these pages actually exist. For example `error: '/auth/error'` refers to a page file at `pages/auth/error.js`.
|
||||
</Callout>
|
||||
:::
|
||||
|
||||
## Error codes
|
||||
|
||||
@@ -178,6 +176,6 @@ You can also use the `signIn()` function which will handle obtaining the CSRF to
|
||||
signIn("credentials", { username: "jsmith", password: "1234" })
|
||||
```
|
||||
|
||||
<Callout type="info">
|
||||
:::tip
|
||||
Remember to put any custom pages in a folder outside **/pages/api** which is reserved for API code. As per the examples above, a location convention suggestion is `pages/auth/...`.
|
||||
</Callout>
|
||||
:::
|
||||
@@ -2,14 +2,11 @@
|
||||
title: Refresh token rotation
|
||||
---
|
||||
|
||||
import { Callout } from "nextra-theme-docs"
|
||||
|
||||
Refresh token rotation is the practice of updating an `access_token` on behalf of the user, without requiring interaction (eg.: re-sign in). `access_token`s are usually issued for a limited time. After they expire, the service verifying them will ignore the value. Instead of asking the user to sign in again to obtain a new `access_token`, certain providers support exchanging a `refresh_token` for a new `access_token`, renewing the expiry time. Let's see how this can be achieved.
|
||||
|
||||
<Callout>
|
||||
Our goal is to add zero-config support for built-in providers eventually. Let
|
||||
us know if you would like to help.
|
||||
</Callout>
|
||||
:::note
|
||||
Our goal is to add zero-config support for built-in providers eventually. Let us know if you would like to help.
|
||||
:::
|
||||
|
||||
## Implementation
|
||||
|
||||
@@ -19,15 +16,13 @@ First, make sure that the provider you want to use supports `refresh_token`'s. C
|
||||
|
||||
Depending on the session strategy, `refresh_token` can be persisted either in a database, or in a cookie, in an encrypted JWT.
|
||||
|
||||
<Callout type="info">
|
||||
Using a JWT to store the `refresh_token` is less secure than saving it in a
|
||||
database, and you need to evaluate based on your requirements which strategy
|
||||
you choose.
|
||||
</Callout>
|
||||
:::info
|
||||
Using a JWT to store the `refresh_token` is less secure than saving it in a database, and you need to evaluate based on your requirements which strategy you choose.
|
||||
:::
|
||||
|
||||
#### JWT strategy
|
||||
|
||||
Using the [jwt](../../reference/03-core/interfaces/types.CallbacksOptions.md#jwt) and [session](../../reference/03-core/interfaces/types.CallbacksOptions.md#session) callbacks, we can persist OAuth tokens and refresh them when they expire.
|
||||
Using the [jwt](../../reference/core/types#jwt) and [session](../../reference/core/types#session) callbacks, we can persist OAuth tokens and refresh them when they expire.
|
||||
|
||||
Below is a sample implementation using Google's Identity Provider. Please note that the OAuth 2.0 request in the `refreshAccessToken()` function will vary between different providers, but the core logic should remain similar.
|
||||
|
||||
@@ -50,10 +45,10 @@ export default Auth(new Request("https://example.com"), {
|
||||
// Save the access token and refresh token in the JWT on the initial login
|
||||
return {
|
||||
access_token: account.access_token,
|
||||
expires_at: Date.now() + account.expires_in * 1000,
|
||||
expires_at: Math.floor(Date.now() / 1000 + account.expires_in),
|
||||
refresh_token: account.refresh_token,
|
||||
}
|
||||
} else if (Date.now() < token.expires_at) {
|
||||
} else if (Date.now() < token.expires_at * 1000) {
|
||||
// If the access token has not expired yet, return it
|
||||
return token
|
||||
} else {
|
||||
@@ -79,7 +74,7 @@ export default Auth(new Request("https://example.com"), {
|
||||
return {
|
||||
...token, // Keep the previous token properties
|
||||
access_token: tokens.access_token,
|
||||
expires_at: Date.now() + tokens.expires_in * 1000,
|
||||
expires_at: Math.floor(Date.now() / 1000 + tokens.expires_in),
|
||||
// Fall back to old refresh token, but note that
|
||||
// many providers may only allow using a refresh token once.
|
||||
refresh_token: tokens.refresh_token ?? token.refresh_token,
|
||||
@@ -141,7 +136,7 @@ export default Auth(new Request("https://example.com"), {
|
||||
const [google] = await prisma.account.findMany({
|
||||
where: { userId: user.id, provider: "google" },
|
||||
})
|
||||
if (google.expires_at >= Date.now()) {
|
||||
if (google.expires_at * 1000 < Date.now()) {
|
||||
// If the access token has expired, try to refresh it
|
||||
try {
|
||||
// https://accounts.google.com/.well-known/openid-configuration
|
||||
@@ -164,7 +159,7 @@ export default Auth(new Request("https://example.com"), {
|
||||
await prisma.account.update({
|
||||
data: {
|
||||
access_token: tokens.access_token,
|
||||
expires_at: Date.now() + tokens.expires_in * 1000,
|
||||
expires_at: Math.floor(Date.now() / 1000 + tokens.expires_in),
|
||||
refresh_token: tokens.refresh_token ?? google.refresh_token,
|
||||
},
|
||||
where: {
|
||||
@@ -227,3 +222,4 @@ return (...)
|
||||
## Source Code
|
||||
|
||||
A working example can be accessed [here](https://github.com/nextauthjs/next-auth-refresh-token-example).
|
||||
|
||||
153
docs/docs/guides/basics/role-based-access-control.md
Normal file
@@ -0,0 +1,153 @@
|
||||
---
|
||||
title: Role-based access control
|
||||
---
|
||||
|
||||
There are two ways to add role-based access control (RBAC) to your application, based on the [session strategy](/concepts/session-strategies) you choose. Let's see an example for each of these.
|
||||
|
||||
## Getting the role
|
||||
|
||||
We are going to start by adding a `profile()` callback to the providers' config to determine the user role:
|
||||
|
||||
```ts title="/pages/api/auth/[...nextauth].ts"
|
||||
import NextAuth from "next-auth"
|
||||
import Google from "next-auth/providers/google"
|
||||
|
||||
export default NextAuth({
|
||||
providers: [
|
||||
Google({
|
||||
profile(profile) {
|
||||
return { role: profile.role ?? "user", ... }
|
||||
},
|
||||
...
|
||||
})
|
||||
],
|
||||
})
|
||||
```
|
||||
|
||||
:::tip
|
||||
To determine the user's role, you can either add your logic or if your provider assigns roles already, use that instead.
|
||||
:::
|
||||
|
||||
## Persisting the role
|
||||
### With JWT
|
||||
|
||||
When you don't have a database configured, the role will be persisted in a cookie, by using the `jwt()` callback. On sign-in, the `role` property is exposed from the `profile` callback on the `user` object. Persist the `user.role` value by assigning it to `token.role`. That's it!
|
||||
|
||||
If you also want to use the role on the client, you can expose it via the `session` callback.
|
||||
|
||||
```ts title="/pages/api/auth/[...nextauth].ts"
|
||||
import NextAuth from "next-auth"
|
||||
import Google from "next-auth/providers/google"
|
||||
|
||||
export default NextAuth({
|
||||
providers: [
|
||||
Google({
|
||||
profile(profile) {
|
||||
return { role: profile.role ?? "user", ... }
|
||||
},
|
||||
...
|
||||
})
|
||||
],
|
||||
// highlight-start
|
||||
callbacks: {
|
||||
jwt({ token, user }) {
|
||||
if(user) token.role = user.role
|
||||
return token
|
||||
},
|
||||
session({ session, token }) {
|
||||
session.user.role = token.role
|
||||
return session
|
||||
}
|
||||
}
|
||||
// highlight-end
|
||||
})
|
||||
```
|
||||
|
||||
:::info
|
||||
With this strategy, if you want to update the role, the user needs to be forced to sign in again.
|
||||
:::
|
||||
|
||||
### With Database
|
||||
|
||||
When you have a database, you can save the user role on the [User model](/reference/adapters/models#user). The below example is showing you how to do this with Prisma, but the idea is the same for all adapters.
|
||||
|
||||
First, add a `role` column to the User model.
|
||||
|
||||
```ts title="/prisma/schema.prisma"
|
||||
model User {
|
||||
id String @id @default(cuid())
|
||||
name String?
|
||||
email String? @unique
|
||||
emailVerified DateTime?
|
||||
image String?
|
||||
role String? // New column
|
||||
accounts Account[]
|
||||
sessions Session[]
|
||||
}
|
||||
```
|
||||
|
||||
The `profile()` callback's return value is used to create users in the database. That's it! Your newly created users will now have an assigned role.
|
||||
|
||||
If you also want to use the role on the client, you can expose it via the `session` callback.
|
||||
|
||||
```ts title="/pages/api/auth/[...nextauth].ts"
|
||||
import NextAuth from "next-auth"
|
||||
import Google from "next-auth/providers/google"
|
||||
// highlight-next-line
|
||||
import prisma from "lib/prisma"
|
||||
|
||||
export default NextAuth({
|
||||
// highlight-next-line
|
||||
adapter: PrismaAdapter(prisma),
|
||||
providers: [
|
||||
Google({
|
||||
profile(profile) {
|
||||
return { role: profile.role ?? "user", ... }
|
||||
}
|
||||
...
|
||||
})
|
||||
],
|
||||
// highlight-start
|
||||
callbacks: {
|
||||
session({ session, user }) {
|
||||
session.user.role = user.role
|
||||
return session
|
||||
}
|
||||
}
|
||||
// highlight-end
|
||||
})
|
||||
```
|
||||
|
||||
:::info
|
||||
It is up to you how you want to manage to update the roles, either through direct database access or building your role update API.
|
||||
:::
|
||||
|
||||
## Using the role
|
||||
|
||||
If you want to use the role in the client, for both cases above, when using the `useSession` hook, `session.user.role` will have the required role if you exposed it via the `session` callback. You can use this to render a different UI for different users.
|
||||
|
||||
```ts title="/pages/admin.tsx"
|
||||
import { useSession } from "next-auth/react"
|
||||
|
||||
export default function Page() {
|
||||
const session = await useSession()
|
||||
|
||||
if (session?.user.role === "admin") {
|
||||
return <p>You are an admin, welcome!</p>
|
||||
}
|
||||
|
||||
return <p>You are not authorized to view this page!</p>
|
||||
}
|
||||
```
|
||||
|
||||
:::tip
|
||||
When using Next.js and JWT, you can alternatively also use [Middleware](https://next-auth.js.org/configuration/nextjs#wrap-middleware) to redirect the user based on their role, even before rendering the page.
|
||||
:::
|
||||
|
||||
## Resources
|
||||
|
||||
- [Concepts: Session strategies](/concepts/session-strategies)
|
||||
- [Next.js: Middleware](https://next-auth.js.org/configuration/nextjs#wrap-middleware)
|
||||
- [Adapters: User model](/reference/adapters/models#user)
|
||||
- [Adapters: Prisma adapter](/reference/adapters/prisma)
|
||||
- [TypeScript](/getting-started/typescript)
|
||||
@@ -2,15 +2,13 @@
|
||||
title: Securing Pages & API routes
|
||||
---
|
||||
|
||||
import { Callout } from "nextra-theme-docs"
|
||||
|
||||
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/)._
|
||||
|
||||
<Callout>
|
||||
:::tip
|
||||
The methods `getSession()` and `getToken()` both return an `object` if a session is valid and `null` if a session is invalid or has expired.
|
||||
</Callout>
|
||||
:::
|
||||
|
||||
## Securing Pages
|
||||
|
||||
@@ -93,7 +91,7 @@ export async function getServerSideProps(context) {
|
||||
}
|
||||
```
|
||||
|
||||
<Callout>
|
||||
:::tip
|
||||
When you supply a `session` prop in `_app.js`, `useSession` won't show a loading state, as it'll already have the session available. In this way, you can provide a more seamless user experience.
|
||||
|
||||
```js title="pages/_app.js"
|
||||
@@ -111,7 +109,7 @@ export default function App({
|
||||
}
|
||||
```
|
||||
|
||||
</Callout>
|
||||
:::
|
||||
|
||||
## Securing API Routes
|
||||
|
||||
@@ -158,12 +156,12 @@ export default async (req, res) => {
|
||||
}
|
||||
```
|
||||
|
||||
<Callout>
|
||||
:::tip
|
||||
You can use the `getToken()` helper function in any application as long as you set the `NEXTAUTH_URL` environment variable and the application is able to read the JWT cookie (e.g. is on the same domain).
|
||||
</Callout>
|
||||
:::
|
||||
|
||||
<Callout>
|
||||
:::note
|
||||
Pass `getToken` the same value for `secret` as specified in `pages/api/auth/[...nextauth].js`.
|
||||
|
||||
See [the documentation for the JWT option](/reference/configuration/auth-config#jwt) for more information.
|
||||
</Callout>
|
||||
:::
|
||||
5
docs/docs/guides/corporate-proxies/_category_.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"label": "Corporate proxies",
|
||||
"collapsible": true,
|
||||
"collapsed": true
|
||||
}
|
||||
@@ -2,18 +2,16 @@
|
||||
title: Corporate proxy
|
||||
---
|
||||
|
||||
import { Callout } from 'nextra-theme-docs'
|
||||
|
||||
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:
|
||||
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 proxies 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)
|
||||
|
||||
Therefore, we'll need to add an additional proxy agent to the http client, such as `https-proxy-agent`.
|
||||
|
||||
<Callout type="info">
|
||||
:::info
|
||||
`openid-client` allows the user to set an `agent` for requests ([source](https://github.com/panva/node-openid-client/blob/main/docs/README.md#customizing-individual-http-requests)).
|
||||
</Callout>
|
||||
:::
|
||||
|
||||
Thanks to [raphaelpc](https://github.com/raphaelpc) for the below diff, which when applied to `v4.2.1`, adds this agent support to the `client.js` file.
|
||||
|
||||
12
docs/docs/guides/index.md
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
title: Overview
|
||||
sidebar_position: 0
|
||||
---
|
||||
|
||||
This section contains guides for common use cases.
|
||||
|
||||
If you can't find what you're looking for, [raise an issue](https://github.com/nextauthjs/next-auth/issues/new?assignees=&labels=triage%2Cdocumentation&template=4_documentation.yml).
|
||||
|
||||
:::warning Warning
|
||||
Guides are being migrated from the [old documentation page](https://next-auth.js.org), so there are going to be references to `next-auth` still. We are continuously working on updating the naming/references.
|
||||
:::
|
||||
5
docs/docs/guides/providers/_category_.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"label": "Providers",
|
||||
"collapsible": true,
|
||||
"collapsed": true
|
||||
}
|
||||
@@ -3,23 +3,21 @@ id: credentials
|
||||
title: Credentials Provider
|
||||
---
|
||||
|
||||
import { Callout } from 'nextra-theme-docs'
|
||||
|
||||
The Credentials provider allows you to handle signing in with arbitrary credentials, such as a username and password, domain, or two factor authentication or hardware device (e.g. YubiKey U2F / FIDO).
|
||||
The Credentials provider allows you to handle signing in with arbitrary credentials, such as a username and password, domain, or two-factor authentication or hardware device (e.g. YubiKey U2F / FIDO).
|
||||
|
||||
It is intended to support use cases where you have an existing system you need to authenticate users against.
|
||||
|
||||
It comes with the constraint that users authenticated in this manner are not persisted in the database, and consequently that the Credentials provider can only be used if JSON Web Tokens are enabled for sessions.
|
||||
|
||||
<Callout type="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.
|
||||
</Callout>
|
||||
:::warning
|
||||
The functionality provided for credentials-based authentication is intentionally limited to discourage the use of passwords due to the inherent security risks associated with them and the additional complexity associated with supporting usernames and passwords.
|
||||
:::
|
||||
|
||||
## Options
|
||||
|
||||
The **Credentials Provider** comes with a set of default options:
|
||||
|
||||
- [Credentials Provider options](/reference/providers/credentials)
|
||||
- [Credentials Provider options](/reference/core/providers_credentials)
|
||||
|
||||
You can override any of the options to suit your own use case.
|
||||
|
||||
@@ -35,7 +33,7 @@ If you return an object it will be persisted to the JSON Web Token and the user
|
||||
|
||||
3. If you throw an Error, the user will be sent to the error page with the error message as a query parameter.
|
||||
|
||||
The Credentials provider's `authorize()` method also provides the request object as the second parameter (see example below).
|
||||
The Credentials provider's `authorize()` method also provides the request object as the second parameter (see the example below).
|
||||
|
||||
```js title="pages/api/auth/[...nextauth].js"
|
||||
import CredentialsProvider from "next-auth/providers/credentials";
|
||||
@@ -91,7 +89,7 @@ You can specify more than one credentials provider by specifying a unique `id` f
|
||||
|
||||
You can also use them in conjunction with other provider options.
|
||||
|
||||
As with all providers, the order you specify them is the order they are displayed on the sign in page.
|
||||
As with all providers, the order you specify is the order they are displayed on the sign-in page.
|
||||
|
||||
```js
|
||||
providers: [
|
||||
112
docs/docs/guides/providers/custom-provider.md
Normal file
@@ -0,0 +1,112 @@
|
||||
---
|
||||
title: OAuth Provider
|
||||
---
|
||||
|
||||
Auth.js comes with a set of built-in OAuth providers that you can import from `@auth/core/providers/*`. Every provider has their separate documentation page under the [core package's API Reference](/reference/core)
|
||||
|
||||
|
||||
## Use your own provider
|
||||
|
||||
However, you can use _any_ provider as long as they are compliant with the OAuth/OIDC specifications.
|
||||
|
||||
Auth.js uses the [`oauth4webapi`](https://github.com/panva/oauth4webapi/blob/main/docs/README.md) package under the hood.
|
||||
|
||||
To use a custom OAuth provider with Auth.js, pass an object to the [`providers` list](/reference/core#providers).
|
||||
|
||||
It can implement either the [`OAuth2Config`](/reference/core/providers#oauth2configprofile) or the [`OIDCConfig`](/reference/core/providers#oidcconfigprofile) interface, depending on if your provider is OAuth 2 or OpenID Connect compliant.
|
||||
|
||||
For example, if you have a fully OIDC-compliant provider, this is all you need:
|
||||
|
||||
```ts
|
||||
import type { OIDCConfig } from "@auth/core/providers"
|
||||
|
||||
...
|
||||
providers: [
|
||||
{
|
||||
id: "my-oidc-provider",
|
||||
name: "My Provider",
|
||||
type: "oidc",
|
||||
issuer: "https://my.oidc-provider.com",
|
||||
clientId: process.env.CLIENT_ID,
|
||||
clientSecret: process.env.CLIENT_SECRET
|
||||
} satisfies OIDCConfig
|
||||
]
|
||||
...
|
||||
```
|
||||
|
||||
Then, you can set the [Redirect URI](https://www.ietf.org/archive/id/draft-ietf-oauth-v2-1-07.html#name-client-redirection-endpoint) in your provider's dashboard to something like `https://app-url.com/{path-to-auth-handler}/callback/my-oidc-provider`.
|
||||
|
||||
`{path-to-auth-handler}` is _usually_ `auth` or `api/auth`, depending on your framework of your choice.
|
||||
`my-oidc-provider` matches the `id` you set in the [`providers` list](/reference/core#providers).
|
||||
|
||||
|
||||
## Override default provider config
|
||||
|
||||
For built-in providers, in most cases you will only need to specify the `clientId` and `clientSecret`, and in case of OIDC providers, the `issuer` property. If you need to override any of the defaults, you can add them in the provider's function call and they will be deep-merged with the default configuration options.
|
||||
|
||||
:::note
|
||||
The user provided options are deeply merged with the default options. That means you only have to override part of the options that you need to be different. For example if you want different scopes, overriding `authorization.params.scope` is enough, instead of the whole `authorization` option.
|
||||
:::
|
||||
|
||||
|
||||
For example, to override a provider's default scopes, you can do the following:
|
||||
|
||||
```ts
|
||||
import Auth0Provider from "@auth/core/providers/auth0"
|
||||
|
||||
Auth0Provider({
|
||||
clientId: process.env.CLIENT_ID,
|
||||
clientSecret: process.env.CLIENT_SECRET,
|
||||
issuer: process.env.ISSUER,
|
||||
authorization: { params: { scope: "openid your_custom_scope" } },
|
||||
})
|
||||
```
|
||||
|
||||
Another example, the `profile` callback will return `id`, `name`, `email` and `picture` by default, but you might want to return more information from the provider. After setting the correct scopes, you can then do something like this:
|
||||
|
||||
```ts
|
||||
import GoogleProvider from "@auth/core/providers/google"
|
||||
|
||||
GoogleProvider({
|
||||
clientId: process.env.GOOGLE_CLIENT_ID,
|
||||
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
|
||||
profile(profile) {
|
||||
return {
|
||||
// Return all the profile information you need.
|
||||
// The only truly required field is `id`
|
||||
// to be able identify the account when added to a database
|
||||
}
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
An example of how to enable automatic account linking:
|
||||
|
||||
```ts
|
||||
import GoogleProvider from "@auth/core/providers/google"
|
||||
|
||||
GoogleProvider({
|
||||
clientId: process.env.GOOGLE_CLIENT_ID,
|
||||
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
|
||||
allowDangerousEmailAccountLinking: true,
|
||||
})
|
||||
```
|
||||
|
||||
## Adding a new built-in provider
|
||||
|
||||
If you think your custom provider might be useful to others, we encourage you to open a PR and add it to the built-in list.
|
||||
|
||||
:::note
|
||||
We are only accepting new providers to `@auth/core`, and not `next-auth`. Follow the steps below to make sure your PR is merged!
|
||||
:::
|
||||
|
||||
1. Create a new `{provider}.ts` (for it to get merged, you must use TypeScript) file under the [`packages/core/src/providers`](https://github.com/nextauthjs/next-auth/tree/main/packages/core/src/providers) directory.
|
||||
2. Make sure that you are following other providers, ie.:
|
||||
- Use a named default export: `export default function YourProvider`
|
||||
- Export the TypeScript `interface` that defines the provider's available user info properties
|
||||
- Add the necessary JSDoc comments/documentation (Study the built-in providers to get an understanding what's needed. For example, the [Auth0 provider](https://github.com/nextauthjs/next-auth/blob/main/packages/core/src/providers/auth0.ts) is a good example for OIDC and the [GitHub Provider](https://github.com/nextauthjs/next-auth/blob/main/packages/core/src/providers/github.ts) is an OAuth provider.)
|
||||
- Add links to the provider's API reference/documentation so others can understand how to use the provider
|
||||
3. Add the new provider name to the `Provider type` dropdown options in [`the provider issue template`](https://github.com/nextauthjs/next-auth/edit/main/.github/ISSUE_TEMPLATE/2_bug_provider.yml)
|
||||
4. (Optional): Add a logo `{provider}.svg` to the [`docs/static/img/providers`](https://github.com/nextauthjs/next-auth/tree/main/docs/static/img/providers) directory.
|
||||
|
||||
That's it! 🎉 Others will be able to discover and use this provider!
|
||||
109
docs/docs/guides/providers/email-http-api.md
Normal file
@@ -0,0 +1,109 @@
|
||||
---
|
||||
id: email-http
|
||||
title: HTTP-based Email Provider
|
||||
---
|
||||
|
||||
## Introduction
|
||||
|
||||
:::note
|
||||
The following guide is written for `next-auth` (NextAuth.js), but it should work for any of the Auth.js framework libraries (`@auth/*`) as well.
|
||||
:::
|
||||
|
||||
|
||||
There is a built-in Email provider with which you could connect to the SMTP server of your choice to send "magic link" emails for sign-in purposes. However, the Email provider can also be used with HTTP-based email services, like AWS SES, Postmark, Sendgrid, etc. In this guide, we are going to explain how to use our Email magic link provider with any of the more modern HTTP-based Email APIs.
|
||||
|
||||
For this example, we will be using [SendGrid](https://sendgrid.com), but any email service providing an HTTP API or JS client library will work.
|
||||
We will also refer to the [Prisma Adapter](/reference/adapter/prisma). A [database adapter](/adapters/overview) is a requirement for the Email provider.
|
||||
|
||||
## Setup
|
||||
|
||||
First, if you do not have a project using Auth.js, clone and set up a basic Auth.js project like the one [provided in](https://github.com/nextauthjs/next-auth-example.git) our example repo](https://github.com/nextauthjs/next-auth-example.git).
|
||||
|
||||
- Install the [Prisma Adapter](/reference/adapter/prisma)
|
||||
- Generate an API key from your cloud Email provider of choice and add it to your `.env.*` file. For example, mine is going to be called `SENDGRID_API`
|
||||
- Add the following configuration to your configuration file:
|
||||
|
||||
```js title="pages/api/auth/[...nextauth].ts"
|
||||
import NextAuth, { NextAuthOptions } from "next-auth"
|
||||
import { PrismaAdapter } from "@next-auth/prisma-adapter"
|
||||
import { PrismaClient } from "@prisma/client"
|
||||
|
||||
const prisma = new PrismaClient()
|
||||
|
||||
export const authOptions: NextAuthOptions = {
|
||||
adapter: PrismaAdapter(prisma),
|
||||
providers: [
|
||||
{
|
||||
id: 'sendgrid',
|
||||
type: 'email',
|
||||
async sendVerificationRequest({identifier: email, url}) {
|
||||
}
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
export default NextAuth(authOptions)
|
||||
```
|
||||
|
||||
Next, all that's left to do is call the HTTP endpoint from our cloud email provider and pass it the required metadata like the `to` address, the email `body`, and any other fields we may need to include.
|
||||
|
||||
As mentioned earlier, we're going to be using SendGrid in this example, so the appropriate endpoint is `https://api.sendgrid.com/v3/mail/send` ([more info](https://docs.sendgrid.com/for-developers/sending-email/api-getting-started)). Therefore, we're going to pull out some of the important information from the `params` argument and use it in a `fetch()` call to the previously mentioned SendGrid API.
|
||||
|
||||
```js title="pages/api/auth/[...nextauth].ts"
|
||||
import NextAuth, { NextAuthOptions } from "next-auth"
|
||||
import { PrismaAdapter } from "@next-auth/prisma-adapter"
|
||||
import { PrismaClient } from "@prisma/client"
|
||||
|
||||
const prisma = new PrismaClient()
|
||||
|
||||
export const authOptions: NextAuthOptions = {
|
||||
adapter: PrismaAdapter(prisma),
|
||||
providers: [
|
||||
{
|
||||
id: 'sendgrid',
|
||||
type: 'email',
|
||||
async sendVerificationRequest({identifier: email, url}) {
|
||||
// highlight-start
|
||||
// Call the cloud Email provider API for sending emails
|
||||
// See https://docs.sendgrid.com/api-reference/mail-send/mail-send
|
||||
const response = await fetch("https://api.sendgrid.com/v3/mail/send", {
|
||||
// The body format will vary depending on provider, please see their documentation
|
||||
// for further details.
|
||||
body: JSON.stringify({
|
||||
personalizations: [{ to: [{ email }] }],
|
||||
from: { email: "noreply@company.com" },
|
||||
subject: "Sign in to Your page",
|
||||
content: [
|
||||
{
|
||||
type: "text/plain",
|
||||
value: `Please click here to authenticate - ${url}`,
|
||||
},
|
||||
],
|
||||
}),
|
||||
headers: {
|
||||
// Authentication will also vary from provider to provider, please see their docs.
|
||||
Authorization: `Bearer ${process.env.SENDGRID_API}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
method: "POST",
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
const { errors } = await response.json()
|
||||
throw new Error(JSON.stringify(errors))
|
||||
}
|
||||
// highlight-end
|
||||
},
|
||||
}
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
And that's all we need to do to send Emails via an HTTP API! Note here that the example is only using `text/plain` as the body type. You'll probably want to change that to `text/html` and pass in a nice-looking HTML email. See, for example, our `html` function in [the Auth.js docs](/providers/email#customizing-emails).
|
||||
|
||||
To sign in via this custom provider, you would refer to it by the `id` in when you are calling the sign-in method, for example: `signIn('sendgrid', { email: 'user@company.com' })`.
|
||||
|
||||
## References
|
||||
|
||||
- [Email provider documentation with HTML generation and more](/reference/core/modules/providers_email)
|
||||
- [SendGrid JSON Body documentation](https://docs.sendgrid.com/api-reference/mail-send/mail-send#body)
|
||||
@@ -3,8 +3,6 @@ id: email
|
||||
title: Email Provider
|
||||
---
|
||||
|
||||
import { Callout } from 'nextra-theme-docs'
|
||||
|
||||
The Email provider uses email to send "magic links" that can be used to sign in, you will likely have seen these if you have used services like Slack before.
|
||||
|
||||
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).
|
||||
@@ -17,15 +15,15 @@ On initial sign in, a **Verification Token** is sent to the email address provid
|
||||
|
||||
If someone provides the email address of an _existing account_ when signing in, an email is sent and they are signed into the account associated with that email address when they follow the link in the email.
|
||||
|
||||
<Callout>
|
||||
:::tip
|
||||
The Email Provider can be used with both JSON Web Tokens and database sessions, but you **must** configure a database to use it. It is not possible to enable email sign in without using a database.
|
||||
</Callout>
|
||||
:::
|
||||
|
||||
## Options
|
||||
|
||||
The **Email Provider** comes with a set of default options:
|
||||
|
||||
- [Email Provider options](/reference/providers/email)
|
||||
- [Email Provider options](/guides/providers/email)
|
||||
|
||||
You can override any of the options to suit your own use case.
|
||||
|
||||
@@ -199,9 +197,9 @@ function text({ url, host }: Record<"url" | "host", string>) {
|
||||
}
|
||||
```
|
||||
|
||||
<Callout>
|
||||
:::tip
|
||||
If you want to generate great looking email client compatible HTML with React, check out https://mjml.io
|
||||
</Callout>
|
||||
:::
|
||||
|
||||
## Customizing the Verification Token
|
||||
|
||||
118
docs/docs/guides/resources.md
Normal file
@@ -0,0 +1,118 @@
|
||||
---
|
||||
id: resources
|
||||
title: Community resources
|
||||
---
|
||||
|
||||
> These tutorials are contributed by the community.
|
||||
> **New submissions and edits are welcome!**
|
||||
|
||||
## Basics
|
||||
|
||||
#### [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 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>
|
||||
|
||||
- Next.js supports multiple patterns for authentication, each designed for different use cases. This guide will allow you to choose your adventure based on your constraints. By Lee Robinson.
|
||||
|
||||
#### [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 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 & 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 Auth.js.
|
||||
|
||||
#### [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 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 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) & 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 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 Auth.js.
|
||||
|
||||
## Fullstack
|
||||
|
||||
#### [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
|
||||
- **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
|
||||
|
||||
The app that we'll work on in this course is called **_SupaVacation_**. It is an online marketplace for vacation rentals where users can browse through all the properties for rent, bookmark their favorite ones, and even rent their own properties.
|
||||
|
||||
> Here's [a live demo](https://supa-vacation.vercel.app/) of the app's final version. It is what your app should look likes after completing this course. Feel free to play with it to get an overview of all the features you'll be working on.
|
||||
|
||||
#### [Magic Link Authentication in Next.js with NextAuth and Fauna](https://alterclass.io/tutorials/magic-link-authentication-in-nextjs-with-nextauth-and-fauna) <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 implement passwordless/magic link authentication with database storage in your Next.js projects using NextAuth and Fauna DB.
|
||||
|
||||
> The final version of the project's code can be found on [Github](https://github.com/AlterClassIO/magic-next-auth). You can use it as a starting point for any Next.js app that requires passwordless authentication.
|
||||
|
||||
> You can also preview the example live [here](https://magic-next-auth.vercel.app/).
|
||||
|
||||
This tutorial covers:
|
||||
|
||||
- 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
|
||||
- Customizing the sign-in email and sending a welcome email to new users
|
||||
|
||||
#### [Passwordless Authentication with Next.js, Prisma, and next-auth](https://dev.to/prisma/passwordless-authentication-with-next-js-prisma-and-next-auth-5g8g) <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>
|
||||
|
||||
- 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 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 Auth.js. By Nikolas Burk at Prisma.
|
||||
|
||||
## Advanced
|
||||
|
||||
#### [Add auth support to a Next.js app with a custom backend](https://arunoda.me/blog/add-auth-support-to-a-next-js-app-with-a-custom-backend) <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.
|
||||
|
||||
#### [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 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 Auth.js.
|
||||
|
||||
#### [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 [Auth.js](https://authjs.dev) to enable passwordless authentication without a database.
|
||||
|
||||
## Database
|
||||
|
||||
#### [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 Auth.js sessions using HarperDB as an example.
|
||||
- Video tutorial also available: <https://www.youtube.com/watch?v=pu7xBv7sZ8s>
|
||||
|
||||
#### [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.
|
||||
5
docs/docs/guides/testing/_category_.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"label": "Testing",
|
||||
"collapsible": true,
|
||||
"collapsed": true
|
||||
}
|
||||
@@ -2,8 +2,6 @@
|
||||
title: Testing with Cypress
|
||||
---
|
||||
|
||||
import { Callout } from 'nextra-theme-docs'
|
||||
|
||||
To test an implementation of Auth.js, we encourage you to use [Cypress](https://cypress.io).
|
||||
|
||||
## Setting up Cypress
|
||||
@@ -14,9 +12,9 @@ To get started, install the dependencies:
|
||||
npm install --save-dev cypress cypress-social-logins @testing-library/cypress
|
||||
```
|
||||
|
||||
<Callout>
|
||||
:::note
|
||||
If you are using username/password based login, you will not need the `cypress-social-login` dependency.
|
||||
</Callout>
|
||||
:::
|
||||
|
||||
Cypress will install and initialize the folder structure with example integration tests, a folder for plugins, etc.
|
||||
|
||||
5
docs/docs/reference/adapters/_category_.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"label": "Database adapters",
|
||||
"collapsible": true,
|
||||
"collapsed": true
|
||||
}
|
||||
@@ -1,9 +1,75 @@
|
||||
---
|
||||
id: models
|
||||
title: Models
|
||||
title: Overview
|
||||
---
|
||||
|
||||
import { Callout } from "nextra-theme-docs"
|
||||
Using a Auth.js / NextAuth.js adapter you can connect to any database service or even several different services at the same time. The following listed official adapters are created and maintained by the community:
|
||||
|
||||
<div class="adapter-card-list">
|
||||
<a href="/reference/adapter/dgraph" class="adapter-card">
|
||||
<img src="/img/adapters/dgraph.png" width="30" />
|
||||
<h4 class="adapter-card__title">Dgraph Adapter</h4>
|
||||
</a>
|
||||
<a href="/reference/adapter/dynamodb" class="adapter-card">
|
||||
<img src="/img/adapters/dynamodb.png" width="30" />
|
||||
<h4 class="adapter-card__title">DynamoDB Adapter</h4>
|
||||
</a>
|
||||
<a href="/reference/adapter/fauna" class="adapter-card">
|
||||
<img src="/img/adapters/fauna.png" width="30" />
|
||||
<h4 class="adapter-card__title">Fauna Adapter</h4>
|
||||
</a>
|
||||
<a href="/reference/adapter/firebase" class="adapter-card">
|
||||
<img src="/img/adapters/firebase.svg" width="40" />
|
||||
<h4 class="adapter-card__title">Firebase Adapter</h4>
|
||||
</a>
|
||||
<a href="/reference/adapter/mikro-orm" class="adapter-card">
|
||||
<img src="/img/adapters/mikro-orm.png" width="30" />
|
||||
<h4 class="adapter-card__title">Mikro ORM Adapter</h4>
|
||||
</a>
|
||||
<a href="/reference/adapter/mongodb" class="adapter-card">
|
||||
<img src="/img/adapters/mongodb.svg" width="15" />
|
||||
<h4 class="adapter-card__title">MongoDB Adapter</h4>
|
||||
</a>
|
||||
<a href="/reference/adapter/neo4j" class="adapter-card">
|
||||
<img src="/img/adapters/neo4j.svg" width="50" />
|
||||
<h4 class="adapter-card__title">Neo4j Adapter</h4>
|
||||
</a>
|
||||
<a href="/reference/adapter/pouchdb" class="adapter-card">
|
||||
<img src="/img/adapters/pouchdb.svg" width="20" />
|
||||
<h4 class="adapter-card__title">PouchDB Adapter</h4>
|
||||
</a>
|
||||
<a href="/reference/adapter/prisma" class="adapter-card">
|
||||
<img src="/img/adapters/prisma.svg" width="30" />
|
||||
<h4 class="adapter-card__title">Prisma Adapter</h4>
|
||||
</a>
|
||||
<a href="/reference/adapter/sequelize" class="adapter-card">
|
||||
<img src="/img/adapters/sequelize.svg" width="30" />
|
||||
<h4 class="adapter-card__title">Sequelize Adapter</h4>
|
||||
</a>
|
||||
<a href="/reference/adapter/supabase" class="adapter-card">
|
||||
<img src="/img/adapters/supabase.svg" width="25" />
|
||||
<h4 class="adapter-card__title">Supabase Adapter</h4>
|
||||
</a>
|
||||
<a href="/reference/adapter/typeorm" class="adapter-card">
|
||||
<img src="/img/adapters/typeorm.png" width="30" />
|
||||
<h4 class="adapter-card__title">TypeORM Adapter</h4>
|
||||
</a>
|
||||
<a href="/reference/adapter/upstash-redis" class="adapter-card">
|
||||
<img src="/img/adapters/upstash-redis.svg" width="30" />
|
||||
<h4 class="adapter-card__title">Upstash Adapter</h4>
|
||||
</a>
|
||||
<a href="/reference/adapter/xata" class="adapter-card">
|
||||
<img src="/img/adapters/xata.svg" width="20" />
|
||||
<h4 class="adapter-card__title">Xata Adapter</h4>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
:::info
|
||||
If you don't find an adapter for the database or service you use, you can always create one yourself. Have a look at our guide on [how to create a database adapter](/guides/adapters/creating-a-database-adapter).
|
||||
:::
|
||||
|
||||
|
||||
## Models
|
||||
|
||||
|
||||
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:
|
||||
|
||||
@@ -49,57 +115,57 @@ erDiagram
|
||||
|
||||
More information about each Model / Table can be found below.
|
||||
|
||||
<Callout>
|
||||
:::note
|
||||
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.
|
||||
</Callout>
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
## User
|
||||
### User
|
||||
|
||||
The User model is for information such as the user's name and email address.
|
||||
|
||||
Email address is optional, but if one is specified for a User then it must be unique.
|
||||
|
||||
<Callout>
|
||||
:::note
|
||||
If a user first signs in with OAuth then their email address is automatically populated using the one from their OAuth profile, if the OAuth provider returns one.
|
||||
|
||||
This provides a way to contact users and for users to maintain access to their account and sign in using email in the event they are unable to sign in with the OAuth provider in future (if the [Email Provider](/getting-started/email-tutorial) is configured).
|
||||
</Callout>
|
||||
:::
|
||||
|
||||
User creation in the database is automatic, and happens when the user is logging in for the first time with a provider. The default data saved is `id`, `name`, `email` and `image`. You can add more profile data by returning extra fields in your [OAuth provider's `profile()`](/reference/providers/oauth) callback.
|
||||
User creation in the database is automatic, and happens when the user is logging in for the first time with a provider. The default data saved is `id`, `name`, `email` and `image`. You can add more profile data by returning extra fields in your [OAuth provider](/guides/providers/custom-provider)'s [`profile()`](/reference/core/providers#profile) callback.
|
||||
|
||||
## Account
|
||||
### Account
|
||||
|
||||
The Account model is for information about OAuth accounts associated with a User. It will usually contain `access_token`, `id_token` and other OAuth specific data. [`TokenSet`](https://github.com/panva/node-openid-client/blob/main/docs/README.md#new-tokensetinput) from `openid-client` might give you an idea of all the fields.
|
||||
|
||||
<Callout>
|
||||
:::note
|
||||
In case of an OAuth 1.0 provider (like Twitter), you will have to look for `oauth_token` and `oauth_token_secret` string fields. GitHub also has an extra `refresh_token_expires_in` integer field. You have to make sure that your database schema includes these fields.
|
||||
</Callout>
|
||||
:::
|
||||
|
||||
A single User can have multiple Accounts, but each Account can only have one User.
|
||||
|
||||
Linking Accounts to Users happen automatically, only when they have the same e-mail address, and the user is currently signed in. Check the [FAQ](/concepts/faq#security) for more information why this is a requirement.
|
||||
|
||||
<Callout>
|
||||
:::tip
|
||||
You can manually unlink accounts, if your adapter implements the `unlinkAccount` method. Make sure to take all the necessary security steps to avoid data loss.
|
||||
</Callout>
|
||||
:::
|
||||
|
||||
<Callout>
|
||||
:::note
|
||||
Linking and unlinking accounts through an API is a planned feature: https://github.com/nextauthjs/next-auth/issues/230
|
||||
</Callout>
|
||||
:::
|
||||
|
||||
## Session
|
||||
### Session
|
||||
|
||||
The Session model is used for database sessions. It is not used if JSON Web Tokens are enabled. Keep in mind, that you can use a database to persist Users and Accounts, and still use JWT for sessions. See the [`session.strategy`](/reference/configuration/auth-config) option.
|
||||
|
||||
A single User can have multiple Sessions, each Session can only have one User.
|
||||
|
||||
<Callout>
|
||||
:::tip
|
||||
When a Session is read, we check if it's `expires` field indicates an invalid session, and delete it from the database. You can also do this clean-up periodically in the background to avoid our extra delete call to the database during an active session retrieval. This might result in a slight performance increase in a few cases.
|
||||
</Callout>
|
||||
:::
|
||||
|
||||
## Verification Token
|
||||
### Verification Token
|
||||
|
||||
The Verification Token model is used to store tokens for passwordless sign in.
|
||||
|
||||
@@ -107,14 +173,19 @@ 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).
|
||||
|
||||
<Callout>
|
||||
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.
|
||||
</Callout>
|
||||
:::note
|
||||
Auth.js makes sure that every token is usable only once, and by default has a short (1 day, can be configured by [`maxAge`](/guides/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.
|
||||
:::
|
||||
|
||||
<Callout>
|
||||
:::tip
|
||||
Due to users forgetting or failing at the sign-in flow, you might end up with unwanted rows in your database, that you might have to periodically clean up to avoid filling the database up with unnecessary data.
|
||||
</Callout>
|
||||
:::
|
||||
|
||||
## RDBMS Naming Convention
|
||||
|
||||
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.
|
||||
Auth.js / NextAuth.js uses `camelCase` for its own database rows, while respecting the conventional `snake_case` formatting for OAuth related values. If mixed casing is an issue for you, most adapters have a dedicated section on how to use a single naming convention.
|
||||
|
||||
|
||||
## TypeScript
|
||||
|
||||
Check out the [`@auth/core/adapters` API Reference](/reference/core/adapters) documentation.
|
||||
32
docs/docs/reference/index.md
Normal file
@@ -0,0 +1,32 @@
|
||||
---
|
||||
title: Overview
|
||||
---
|
||||
|
||||
This section of the documentation contains the API reference for all the official packages under the `@auth/*` and `@next-auth/*` scopes.
|
||||
|
||||
:::warning Warning
|
||||
The API reference is being migrated from the [old documentation page](https://next-auth.js.org), so there are going to be references to `next-auth` still. We are continuously working on updating the naming/references.
|
||||
:::
|
||||
|
||||
## Roadmap
|
||||
|
||||
Here are the _currently_ planned and released packages under the `@auth/*` scope. This is not an exhaustive list, but the set of packages that we would like to focus on to begin with.
|
||||
|
||||
| Feature | Status |
|
||||
| ------------------- | -------- |
|
||||
| `@auth/nextjs` | Planned |
|
||||
| `@auth/*-adapter` | Planned |
|
||||
| `@auth/core` | Experimental |
|
||||
| `@auth/sveltekit` | Experimental |
|
||||
| `@auth/solid-start` | Experimental |
|
||||
|
||||
### Community Packages
|
||||
|
||||
While we are migrating the documentation and working on stabilizing the core package, the community has been working on some packages that are already available. With collaboration, we hope to make these packages official in the future.
|
||||
|
||||
:::note
|
||||
If you are a maintainer of a package, [reach out](https://twitter.com/balazsorban44) if you want to collaborate on making it official or open a PR to add it to the list below, so others can discover it more easily.
|
||||
:::
|
||||
|
||||
- ...
|
||||
- ...
|
||||
@@ -23,8 +23,8 @@ AUTH_SECRET=your_auth_secret
|
||||
in this example we are using github so make sure to set the following environment variables:
|
||||
|
||||
```
|
||||
GITHUB_ID=your_github_oatuh_id
|
||||
GITHUB_SECRET=your_github_oatuh_secret
|
||||
GITHUB_ID=your_github_oauth_id
|
||||
GITHUB_SECRET=your_github_oauth_secret
|
||||
```
|
||||
|
||||
```ts
|
||||
@@ -11,7 +11,7 @@ When using SSR, I recommend creating a `Protected` component that will trigger s
|
||||
|
||||
```tsx
|
||||
// components/Protected.tsx
|
||||
import { type Session } from "@auth/core";
|
||||
import { type Session } from "@auth/core/types";
|
||||
import { getSession } from "@auth/solid-start";
|
||||
import { Component, Show } from "solid-js";
|
||||
import { useRouteData } from "solid-start";
|
||||
@@ -60,7 +60,7 @@ import Protected from "~/components/Protected";
|
||||
export const { routeData, Page } = Protected((session) => {
|
||||
return (
|
||||
<main class="flex flex-col gap-2 items-center">
|
||||
<h1>This is a proteced route</h1>
|
||||
<h1>This is a protected route</h1>
|
||||
</main>
|
||||
);
|
||||
});
|
||||
@@ -110,7 +110,7 @@ And now you can easily create a protected route:
|
||||
export default () => {
|
||||
return (
|
||||
<main class="flex flex-col gap-2 items-center">
|
||||
<h1>This is a proteced route</h1>
|
||||
<h1>This is a protected route</h1>
|
||||
</main>
|
||||
);
|
||||
};
|
||||
15
docs/docs/reference/warnings.md
Normal file
@@ -0,0 +1,15 @@
|
||||
---
|
||||
id: warnings
|
||||
title: Warnings
|
||||
---
|
||||
|
||||
A list of warnings from Auth.js that need your attention.
|
||||
|
||||
|
||||
## Debug enabled
|
||||
|
||||
The `debug` option was evaluated to `true`. It adds extra logs in the terminal which is useful in development, but since it can print sensitive information about users, make sure to set this to `false` in production. In Node.js environments, you can for example set `debug: process.env.NODE_ENV !== "production"`. Consult with your runtime/framework on how to set this value correctly.
|
||||
|
||||
## CSRF disabled
|
||||
|
||||
You were trying to get a CSRF response from Auth.js (eg.: by calling a `/csrf` endpoint), but in this setup, CSRF protection via Auth.js was turned off. This is likely if you are not directly using `@auth/core` but a framework library (like `@auth/sveltekit`) that already has CSRF protection built-in. You likely won't need the CSRF response.
|
||||
@@ -2,7 +2,15 @@
|
||||
title: Security
|
||||
---
|
||||
|
||||
import { Callout } from 'nextra-theme-docs'
|
||||
## Supported Versions
|
||||
|
||||
Security updates are only released for the current version.
|
||||
|
||||
Old releases are not maintained and do not receive updates.
|
||||
|
||||
:::caution
|
||||
`@auth/*` packages are currently under development and - unless stated otherwise - they are not considered ready for production yet. That said, we encourage you to reach out to us if you have any questions or concerns via the below-mentioned channels. We are committed to making Auth.js a secure and reliable solution for your authentication needs.
|
||||
:::
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
@@ -15,16 +23,11 @@ If you contact us regarding a serious issue:
|
||||
- We will endeavor to get back to you within 72 hours.
|
||||
- We will aim to publish a fix within 30 days.
|
||||
- We will disclose the issue (and credit you, with your consent) once a fix to resolve the issue has been released.
|
||||
- If 90 days has elapsed and we still don't have a fix, we will disclose the issue publicly.
|
||||
- If 90 days have elapsed and we still don't have a fix, we will disclose the issue publicly.
|
||||
|
||||
The best way to report an issue is by contacting us via email at info@balazsorban.com or me@iaincollins.com and yo@ndo.dev, or raise a public issue requesting someone get in touch with you via whatever means you prefer for more details. (Please do not disclose sensitive details publicly at this stage.)
|
||||
The best way to report an issue is by contacting us via email at info@balazsorban.com, hi@thvu.dev and yo@ndo.dev, or raise a public issue requesting someone get in touch with you via whatever means you prefer for more details. (Please do not disclose sensitive details publicly at this stage.)
|
||||
|
||||
<Callout>
|
||||
:::note
|
||||
For less serious issues (e.g. RFC compliance for unsupported flows or potential issues that may cause a problem in the future) it is appropriate to make these public as bug reports or feature requests or to raise a question to open a discussion around them.
|
||||
</Callout>
|
||||
:::
|
||||
|
||||
## Supported Versions
|
||||
|
||||
Security updates are only released for the current version.
|
||||
|
||||
Old releases are not maintained and do not receive updates.
|
||||
365
docs/docusaurus.config.js
Normal file
@@ -0,0 +1,365 @@
|
||||
// @ts-check
|
||||
|
||||
const fs = require("fs")
|
||||
const path = require("path")
|
||||
|
||||
// list providers entries from @auth/core/providers/*.ts
|
||||
const coreSrc = "../packages/core/src"
|
||||
const providers = fs
|
||||
.readdirSync(path.join(__dirname, coreSrc, "/providers"))
|
||||
.filter((file) => file.endsWith(".ts") && !file.startsWith("oauth"))
|
||||
.map((p) => `${coreSrc}/providers/${p}`)
|
||||
|
||||
const typedocConfig = require("./typedoc.json")
|
||||
// @ts-expect-error
|
||||
delete typedocConfig.$schema
|
||||
|
||||
/**
|
||||
* @param {string} name
|
||||
* @returns Record<[string, any]>
|
||||
*/
|
||||
function typedocAdapter(name) {
|
||||
const slug = name.toLowerCase().replace(" ", "-")
|
||||
|
||||
return [
|
||||
"docusaurus-plugin-typedoc",
|
||||
{
|
||||
id: slug,
|
||||
plugin: [require.resolve("./typedoc-mdn-links")],
|
||||
watch: process.env.TYPEDOC_WATCH,
|
||||
entryPoints: [`../packages/adapter-${slug}/src/index.ts`],
|
||||
tsconfig: `../packages/adapter-${slug}/tsconfig.json`,
|
||||
out: `reference/adapter/${slug}`,
|
||||
sidebar: {
|
||||
indexLabel: name,
|
||||
},
|
||||
...typedocConfig,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
/** @type {import("@docusaurus/types").Config} */
|
||||
const docusaurusConfig = {
|
||||
markdown: {
|
||||
mermaid: true,
|
||||
},
|
||||
themes: ["@docusaurus/theme-mermaid"],
|
||||
title: "Auth.js",
|
||||
tagline: "Authentication for the Web.",
|
||||
url: "https://authjs.dev",
|
||||
baseUrl: "/",
|
||||
favicon: "img/favicon.ico",
|
||||
trailingSlash: false,
|
||||
organizationName: "nextauthjs",
|
||||
// TODO: remove this once ready
|
||||
onBrokenLinks: "log",
|
||||
projectName: "next-auth",
|
||||
themeConfig: {
|
||||
prism: {
|
||||
theme: require("prism-react-renderer/themes/nightOwl"),
|
||||
magicComments: [
|
||||
{
|
||||
className: "theme-code-block-highlighted-line",
|
||||
line: "highlight-next-line",
|
||||
block: { start: "highlight-start", end: "highlight-end" },
|
||||
},
|
||||
],
|
||||
},
|
||||
algolia: {
|
||||
appId: "OUEDA16KPG",
|
||||
apiKey: "97c0894508f2d1d4a2fef4fe6db28448",
|
||||
indexName: "next-auth",
|
||||
searchParameters: {},
|
||||
contextualSearch: false,
|
||||
externalUrlRegex: "authjs\\.dev|next-auth\\.js\\.org",
|
||||
},
|
||||
navbar: {
|
||||
title: "Auth.js",
|
||||
logo: {
|
||||
alt: "Auth.js Logo",
|
||||
src: "img/logo/logo-xs.webp",
|
||||
},
|
||||
items: [
|
||||
{
|
||||
to: "/getting-started/introduction",
|
||||
activeBasePath: "/getting-started/",
|
||||
label: "Getting started",
|
||||
position: "left",
|
||||
},
|
||||
{
|
||||
to: "/guides",
|
||||
activeBasePath: "/guides",
|
||||
label: "Guides",
|
||||
position: "left",
|
||||
},
|
||||
{
|
||||
to: "/reference",
|
||||
activeBasePath: "/reference",
|
||||
label: "API Reference",
|
||||
position: "left",
|
||||
},
|
||||
{
|
||||
to: "/concepts/faq",
|
||||
activeBasePath: "/concepts",
|
||||
label: "Concepts",
|
||||
position: "left",
|
||||
},
|
||||
{
|
||||
to: "/security",
|
||||
activeBasePath: "/security",
|
||||
label: "Security",
|
||||
position: "left",
|
||||
},
|
||||
{
|
||||
type: "docsVersionDropdown",
|
||||
position: "right",
|
||||
dropdownActiveClassDisabled: true,
|
||||
dropdownItemsAfter: [
|
||||
{
|
||||
to: "https://github.com/nextauthjs/next-auth/releases",
|
||||
label: "All Releases",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
to: "https://www.npmjs.com/package/next-auth",
|
||||
label: "npm",
|
||||
position: "right",
|
||||
},
|
||||
{
|
||||
to: "https://github.com/nextauthjs/next-auth",
|
||||
label: "GitHub",
|
||||
position: "right",
|
||||
},
|
||||
],
|
||||
},
|
||||
announcementBar: {
|
||||
id: "new-major-announcement",
|
||||
content:
|
||||
"<a target='_blank' rel='noopener noreferrer' href='https://next-auth.js.org'>NextAuth.js</a> is becoming Auth.js! 🎉 <a target='_blank' rel='noopener noreferrer' href='https://twitter.com/balazsorban44/status/1603082914362986496'>Read the announcement.</a> Note, this site is under active development. 🏗",
|
||||
backgroundColor: "#000",
|
||||
textColor: "#fff",
|
||||
},
|
||||
footer: {
|
||||
links: [
|
||||
{
|
||||
title: "About Auth.js",
|
||||
items: [
|
||||
{
|
||||
label: "Introduction",
|
||||
to: "/getting-started/introduction",
|
||||
},
|
||||
{
|
||||
html: `
|
||||
<a target="_blank" rel="noopener noreferrer" href="https://vercel.com?utm_source=authjs&utm_campaign=oss">
|
||||
<img
|
||||
alt="Powered by Vercel"
|
||||
style="margin-top: 8px"
|
||||
height="32"
|
||||
width="167"
|
||||
src="https://raw.githubusercontent.com/nextauthjs/next-auth/main/docs/static/img/powered-by-vercel.svg"
|
||||
/>
|
||||
</a>`,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Download",
|
||||
items: [
|
||||
{
|
||||
label: "GitHub",
|
||||
to: "https://github.com/nextauthjs/next-auth",
|
||||
},
|
||||
{
|
||||
label: "NPM",
|
||||
to: "https://www.npmjs.com/package/next-auth",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Acknowledgements",
|
||||
items: [
|
||||
{
|
||||
label: "Contributors",
|
||||
to: "/contributors",
|
||||
},
|
||||
{
|
||||
label: "Sponsors",
|
||||
to: "https://opencollective.com/nextauth",
|
||||
},
|
||||
{
|
||||
label: "Images by unDraw",
|
||||
to: "https://undraw.co/",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
copyright: `Auth.js © Balázs Orbán ${new Date().getFullYear()}`,
|
||||
},
|
||||
colorMode: {
|
||||
respectPrefersColorScheme: true,
|
||||
},
|
||||
docs: {
|
||||
sidebar: {
|
||||
autoCollapseCategories: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
presets: [
|
||||
[
|
||||
"@docusaurus/preset-classic",
|
||||
{
|
||||
docs: {
|
||||
breadcrumbs: false,
|
||||
routeBasePath: "/",
|
||||
sidebarPath: require.resolve("./sidebars.js"),
|
||||
editUrl: "https://github.com/nextauthjs/next-auth/edit/main/docs",
|
||||
lastVersion: "current",
|
||||
showLastUpdateAuthor: true,
|
||||
showLastUpdateTime: true,
|
||||
remarkPlugins: [require("@sapphire/docusaurus-plugin-npm2yarn2pnpm").npm2yarn2pnpm],
|
||||
versions: {
|
||||
current: {
|
||||
label: "experimental",
|
||||
},
|
||||
},
|
||||
},
|
||||
theme: {
|
||||
customCss: require.resolve("./src/css/index.css"),
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
plugins: [
|
||||
[
|
||||
"docusaurus-plugin-typedoc",
|
||||
{
|
||||
...typedocConfig,
|
||||
id: "core",
|
||||
plugin: [require.resolve("./typedoc-mdn-links")],
|
||||
watch: process.env.TYPEDOC_WATCH,
|
||||
entryPoints: ["index.ts", "adapters.ts", "errors.ts", "jwt.ts", "types.ts"].map((e) => `${coreSrc}/${e}`).concat(providers),
|
||||
tsconfig: "../packages/core/tsconfig.json",
|
||||
out: "reference/core",
|
||||
sidebar: {
|
||||
indexLabel: "index",
|
||||
},
|
||||
},
|
||||
],
|
||||
[
|
||||
"docusaurus-plugin-typedoc",
|
||||
{
|
||||
...typedocConfig,
|
||||
id: "sveltekit",
|
||||
plugin: [require.resolve("./typedoc-mdn-links")],
|
||||
watch: process.env.TYPEDOC_WATCH,
|
||||
entryPoints: ["index.ts", "client.ts"].map((e) => `../packages/frameworks-sveltekit/src/lib/${e}`),
|
||||
tsconfig: "../packages/frameworks-sveltekit/tsconfig.json",
|
||||
out: "reference/sveltekit",
|
||||
sidebar: {
|
||||
indexLabel: "index",
|
||||
},
|
||||
},
|
||||
],
|
||||
typedocAdapter("Dgraph"),
|
||||
typedocAdapter("DynamoDB"),
|
||||
typedocAdapter("Fauna"),
|
||||
typedocAdapter("Firebase"),
|
||||
typedocAdapter("Mikro ORM"),
|
||||
typedocAdapter("MongoDB"),
|
||||
typedocAdapter("Neo4j"),
|
||||
typedocAdapter("PouchDB"),
|
||||
typedocAdapter("Prisma"),
|
||||
[
|
||||
"docusaurus-plugin-typedoc",
|
||||
{
|
||||
...typedocConfig,
|
||||
id: "typeorm",
|
||||
plugin: [require.resolve("./typedoc-mdn-links")],
|
||||
watch: process.env.TYPEDOC_WATCH,
|
||||
entryPoints: [`../packages/adapter-typeorm-legacy/src/index.ts`],
|
||||
tsconfig: `../packages/adapter-typeorm-legacy/tsconfig.json`,
|
||||
out: `reference/adapter/typeorm`,
|
||||
sidebar: { indexLabel: "TypeORM" },
|
||||
},
|
||||
],
|
||||
typedocAdapter("Sequelize"),
|
||||
typedocAdapter("Supabase"),
|
||||
typedocAdapter("Upstash Redis"),
|
||||
typedocAdapter("Xata"),
|
||||
],
|
||||
}
|
||||
|
||||
docusaurusConfig.headTags = [
|
||||
{
|
||||
tagName: "meta",
|
||||
attributes: {
|
||||
charSet: "utf-8",
|
||||
},
|
||||
},
|
||||
{
|
||||
tagName: "link",
|
||||
attributes: {
|
||||
rel: "canonical",
|
||||
href: docusaurusConfig.url,
|
||||
},
|
||||
},
|
||||
{
|
||||
tagName: "meta",
|
||||
attributes: {
|
||||
property: "og:title",
|
||||
content: docusaurusConfig.title,
|
||||
},
|
||||
},
|
||||
{
|
||||
tagName: "meta",
|
||||
attributes: {
|
||||
property: "og:description",
|
||||
content: docusaurusConfig.tagline,
|
||||
},
|
||||
},
|
||||
{
|
||||
tagName: "meta",
|
||||
attributes: {
|
||||
property: "og:image",
|
||||
content: `${docusaurusConfig.url}/img/og-image.png`,
|
||||
},
|
||||
},
|
||||
{
|
||||
tagName: "meta",
|
||||
attributes: {
|
||||
property: "og:url",
|
||||
content: docusaurusConfig.url,
|
||||
},
|
||||
},
|
||||
{
|
||||
tagName: "meta",
|
||||
attributes: {
|
||||
name: "twitter:card",
|
||||
content: "summary_large_image",
|
||||
},
|
||||
},
|
||||
{
|
||||
tagName: "meta",
|
||||
attributes: {
|
||||
name: "twitter:title",
|
||||
content: docusaurusConfig.title,
|
||||
},
|
||||
},
|
||||
{
|
||||
tagName: "meta",
|
||||
attributes: {
|
||||
name: "twitter:description",
|
||||
content: docusaurusConfig.tagline,
|
||||
},
|
||||
},
|
||||
{
|
||||
tagName: "meta",
|
||||
attributes: {
|
||||
name: "twitter:image",
|
||||
content: `${docusaurusConfig.url}/img/og-image.png`,
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
module.exports = docusaurusConfig
|
||||
5
docs/next-env.d.ts
vendored
@@ -1,5 +0,0 @@
|
||||
/// <reference types="next" />
|
||||
/// <reference types="next/image-types/global" />
|
||||
|
||||
// NOTE: This file should not be edited
|
||||
// see https://nextjs.org/docs/basic-features/typescript for more information.
|
||||
@@ -1,26 +0,0 @@
|
||||
import withNextra from "nextra"
|
||||
import RemarkLinkRewrite from "remark-link-rewrite"
|
||||
|
||||
export default withNextra({
|
||||
theme: "nextra-theme-docs",
|
||||
themeConfig: "./theme.config.jsx",
|
||||
mdxOptions: {
|
||||
format: "detect",
|
||||
remarkPlugins: [
|
||||
[
|
||||
RemarkLinkRewrite,
|
||||
{
|
||||
replacer(url) {
|
||||
if (url.includes(".md")) {
|
||||
url = url.replace(/\.md$/, "").replace(".md#", "#")
|
||||
}
|
||||
if (url.startsWith("https://authjs.dev")) {
|
||||
url = url.replace("https://authjs.dev", "")
|
||||
}
|
||||
return url
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
})()
|
||||
@@ -1,33 +1,53 @@
|
||||
{
|
||||
"private": true,
|
||||
"repository": "https://github.com/nextauthjs/next-auth",
|
||||
"name": "docs",
|
||||
"version": "0.0.1",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"typedoc": "typedoc",
|
||||
"dev": "TYPEDOC_WATCH=1 pnpm typedoc & next dev",
|
||||
"start": "next start",
|
||||
"build": "next build"
|
||||
"start": "TYPEDOC_WATCH=true docusaurus start --no-open",
|
||||
"dev": "pnpm providers && pnpm snippets && pnpm start",
|
||||
"build": "pnpm providers && docusaurus build",
|
||||
"docusaurus": "docusaurus",
|
||||
"swizzle": "docusaurus swizzle",
|
||||
"deploy": "docusaurus deploy",
|
||||
"serve": "docusaurus serve",
|
||||
"clear": "docusaurus clear",
|
||||
"providers": "node scripts/generate-providers.mjs",
|
||||
"snippets": "node scripts/generate-snippets.mjs"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "ndom91 <yo@ndo.dev> (https://ndo.dev/)",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@codesandbox/sandpack-react": "^2.0.6",
|
||||
"framer-motion": "^8.4.3",
|
||||
"next": "13.2.4",
|
||||
"nextra": "^2.2.19",
|
||||
"nextra-theme-docs": "^2.2.19",
|
||||
"@mdx-js/react": "1.6.22",
|
||||
"@sapphire/docusaurus-plugin-npm2yarn2pnpm": "1.1.4",
|
||||
"classnames": "^2.3.2",
|
||||
"mdx-mermaid": "1.2.2",
|
||||
"mermaid": "9.0.1",
|
||||
"prism-react-renderer": "1.3.5",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"remark-link-rewrite": "^1.0.6",
|
||||
"typedoc": "^0.23.24",
|
||||
"typedoc-plugin-markdown": "next"
|
||||
"react-marquee-slider": "^1.1.5",
|
||||
"styled-components": "5.3.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"autoprefixer": "^10.4.13",
|
||||
"eslint-config-next": "^13.2.4",
|
||||
"postcss": "^8.4.21",
|
||||
"tailwindcss": "^3.2.4"
|
||||
"@docusaurus/core": "2.3.1",
|
||||
"@docusaurus/eslint-plugin": "2.3.1",
|
||||
"@docusaurus/module-type-aliases": "2.3.1",
|
||||
"@docusaurus/preset-classic": "2.3.1",
|
||||
"@docusaurus/theme-common": "2.3.1",
|
||||
"@docusaurus/theme-mermaid": "2.3.1",
|
||||
"@docusaurus/types": "2.3.1",
|
||||
"docusaurus-plugin-typedoc": "1.0.0-next.2",
|
||||
"typedoc": "^0.23.28",
|
||||
"typedoc-plugin-markdown": "4.0.0-next.3"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
import { NotFoundPage } from 'nextra-theme-docs'
|
||||
|
||||
# 404 - This page could not be found
|
||||
|
||||
<NotFoundPage />
|
||||
@@ -1,5 +0,0 @@
|
||||
import { ServerSideErrorPage } from 'nextra-theme-docs'
|
||||
|
||||
# 500 - Internal Server Error
|
||||
|
||||
<ServerSideErrorPage />
|
||||
@@ -1,5 +0,0 @@
|
||||
import "../styles/index.css"
|
||||
|
||||
export default function NextraApp({ Component, pageProps }) {
|
||||
return <Component {...pageProps} />
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
import Document, { Html, Head, Main, NextScript } from "next/document"
|
||||
import { SkipNavLink } from "nextra-theme-docs"
|
||||
|
||||
class MyDocument extends Document {
|
||||
render() {
|
||||
return (
|
||||
<Html lang="en">
|
||||
<Head />
|
||||
<body>
|
||||
<SkipNavLink styled />
|
||||
<Main />
|
||||
<NextScript />
|
||||
</body>
|
||||
</Html>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default MyDocument
|
||||
@@ -1,57 +0,0 @@
|
||||
{
|
||||
"docs": {
|
||||
"title": "Docs",
|
||||
"type": "page",
|
||||
"href": "/getting-started/introduction"
|
||||
},
|
||||
"frameworks": {
|
||||
"title": "Frameworks",
|
||||
"type": "page",
|
||||
"href": "/reference"
|
||||
},
|
||||
"examples": {
|
||||
"type": "page",
|
||||
"title": "Playground",
|
||||
"theme": {
|
||||
"layout": "full",
|
||||
"sidebar": false
|
||||
}
|
||||
},
|
||||
"index": {
|
||||
"title": "Home",
|
||||
"type": "page",
|
||||
"display": "hidden",
|
||||
"theme": {
|
||||
"sidebar": false,
|
||||
"footer": false,
|
||||
"layout": "raw"
|
||||
}
|
||||
},
|
||||
"getting-started": "Getting Started",
|
||||
"guides": "Guides",
|
||||
"reference": "Reference",
|
||||
"concepts": "Concepts",
|
||||
"--": {
|
||||
"type": "separator"
|
||||
},
|
||||
"contributors": "Contributors",
|
||||
"github-link": {
|
||||
"title": "Auth.js Repo",
|
||||
"href": "https://github.com/nextauthjs/next-auth",
|
||||
"newWindow": true
|
||||
},
|
||||
"404": {
|
||||
"type": "page",
|
||||
"theme": {
|
||||
"timestamp": false,
|
||||
"typesetting": "article"
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"type": "page",
|
||||
"theme": {
|
||||
"timestamp": false,
|
||||
"typesetting": "article"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"faq": "FAQ",
|
||||
"oauth": "OAuth"
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
{
|
||||
"basic": {
|
||||
"title": "Basic Usage",
|
||||
"theme": {
|
||||
"layout": "full",
|
||||
"sidebar": false,
|
||||
"breadcrumb": false,
|
||||
"pagination": false,
|
||||
"timestamp": false,
|
||||
"toc": false,
|
||||
"typesetting": "article",
|
||||
"footer": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
---
|
||||
title: Playground
|
||||
full: true
|
||||
---
|
||||
|
||||
<iframe
|
||||
src="https://codesandbox.io/p/sandbox/auth-js-example-01-lkxnqf?editorsize=30&module=%2Fpages%2F_app.tsx&codemirror=1&fontsize=14&theme=dark"
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '94%',
|
||||
border: 0,
|
||||
overflow: 'hidden',
|
||||
background: 'rgb(21, 21, 21)'
|
||||
}}
|
||||
title="NextAuth.js Basic Example"
|
||||
allow="accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking"
|
||||
sandbox="allow-autoplay allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"
|
||||
/>
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"credentials-tutorial": "Credentials Authentication",
|
||||
"databases": "Databases",
|
||||
"email-tutorial": "Email Authentication",
|
||||
"introduction": "Introduction",
|
||||
"oauth-tutorial": "OAuth Authentication",
|
||||
"typescript": "Typescript",
|
||||
"security": "Security",
|
||||
"img": {
|
||||
"display": "hidden"
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
---
|
||||
title: Databasess
|
||||
---
|
||||
|
||||
import { Callout } from 'nextra-theme-docs'
|
||||
|
||||
Auth.js offers multiple database adapters. Check our guides on:
|
||||
|
||||
- [Using an existing database adapter](/guides/adapters/using-a-database-adapter)
|
||||
- [Creating your own](/guides/adapters/creating-a-database-adapter)
|
||||
|
||||
<Callout type="info">
|
||||
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.
|
||||
</Callout>
|
||||
|
||||
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 Auth.js with other databases using a [custom adapter](/guides/adapters/creating-a-database-adapter).
|
||||
@@ -1,56 +0,0 @@
|
||||
---
|
||||
title: Introduction
|
||||
sidebar_position: 0
|
||||
---
|
||||
|
||||
## About Auth.js
|
||||
|
||||
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.
|
||||
|
||||
Check our tutorials to see how easy it is to use Auth.js for authentication:
|
||||
|
||||
- [Setup with OAuth](/getting-started/oauth-tutorial)
|
||||
- [Setup with magic links](/getting-started/email-tutorial)
|
||||
- [Integrating with external auth](/getting-started/credentials-tutorial)
|
||||
|
||||
### Flexible and easy to use
|
||||
|
||||
- Designed to work with any OAuth service, it supports OAuth 1.0, 1.0A, 2.0 and OpenID Connect
|
||||
- Built-in support for [many popular sign-in services](/reference/providers/oauth-builtin)
|
||||
- Supports [email / passwordless authentication](/getting-started/email-tutorial)
|
||||
- Supports stateless authentication with [any backend](/getting-started/credentials-tutorial) (Active Directory, LDAP, etc)
|
||||
- Supports both JSON Web Tokens and database sessions
|
||||
- Designed for Serverless but runs anywhere (AWS Lambda, Docker, Heroku, etc…)
|
||||
|
||||
### Own your own data
|
||||
|
||||
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
|
||||
- Built-in support for [MySQL, MariaDB, Postgres, SQL Server, MongoDB and SQLite](/getting-started/databases)
|
||||
- Works great with databases from popular hosting providers
|
||||
- Can also be used _without a database_ (e.g. OAuth + JWT)
|
||||
|
||||
_Note: Email sign-in requires a database to be configured to store single-use verification tokens._
|
||||
|
||||
### Secure by default
|
||||
|
||||
- Promotes the use of passwordless sign-in mechanisms
|
||||
- Designed to be secure by default and encourage best practices for safeguarding user data
|
||||
- Uses Cross-Site Request Forgery Tokens on POST routes (sign in, sign out)
|
||||
- Default cookie policy aims for the most restrictive policy appropriate for each cookie
|
||||
- When JSON Web Tokens are enabled, they are encrypted by default (JWE) with A256GCM
|
||||
- Auto-generates symmetric signing and encryption keys for developer convenience
|
||||
- Features tab/window syncing and keepalive messages to support short-lived sessions
|
||||
- Attempts to implement the latest guidance published by [Open Web Application Security Project](https://owasp.org/)
|
||||
|
||||
Advanced options allow you to define your own routines to handle controlling what accounts are allowed to sign in, for encoding and decoding JSON Web Tokens and to set custom cookie security policies and session properties, so you can control who can sign in and how often sessions have to be re-validated.
|
||||
|
||||
## Credits
|
||||
|
||||
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 Auth.js, you can find more information on our [OpenCollective](https://opencollective.com/nextauth) page.
|
||||
@@ -1,302 +0,0 @@
|
||||
---
|
||||
title: OAuth authentication
|
||||
---
|
||||
|
||||
import { Callout } from "nextra-theme-docs"
|
||||
import Image from "next/image"
|
||||
|
||||
import creatingOauthAppImg from "./img/getting-started-creating-oauth-app.png"
|
||||
import addingCallbackUrlImg from "./img/getting-started-oauth-callback-url.png"
|
||||
import gettingClientIdSecretImg from "./img/getting-started-oauth-clientid-secret.png"
|
||||
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 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 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**.
|
||||
|
||||
<Callout type="info">
|
||||
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, SolidStart and Gatsby.
|
||||
</Callout>
|
||||
|
||||
## 1. Configuring Auth.js
|
||||
|
||||
### Creating the server config
|
||||
|
||||
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 Auth.js which describes your global auth configuration:
|
||||
|
||||
```ts title="pages/api/auth/[...nextauth].js"
|
||||
import NextAuth from "next-auth"
|
||||
import GithubProvider from "next-auth/providers/github"
|
||||
|
||||
export default NextAuth({
|
||||
providers: [
|
||||
GithubProvider({
|
||||
clientId: process.env.GITHUB_ID,
|
||||
clientSecret: process.env.GITHUB_SECRET,
|
||||
}),
|
||||
],
|
||||
})
|
||||
```
|
||||
|
||||
Behind the scenes this creates all the relevant OAuth API routes within `/api/auth/*` so that auth API requests to:
|
||||
|
||||
- `/api/auth/callback`
|
||||
- `/api/auth/signIn`
|
||||
- `/api/auth/signOut`
|
||||
- etc...
|
||||
|
||||
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.
|
||||
|
||||
`NEXTAUTH_SECRET` is a random string used by the library to encrypt tokens and email verification hashes, and **it's mandatory to keep things secure**! 🔥 🔐 . You can use:
|
||||
|
||||
```
|
||||
$ openssl rand -base64 32
|
||||
```
|
||||
|
||||
or https://generate-secret.vercel.app/32 to generate a random value for it.
|
||||
|
||||
<Callout type="info">
|
||||
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).
|
||||
</Callout>
|
||||
|
||||
### Exposing the session via provider
|
||||
|
||||
To be able to use `useSession` first you'll need to expose the session context, [`<SessionProvider />`](/reference/react/#sessionprovider), at the top level of your application:
|
||||
|
||||
```ts title="pages/_app.ts"
|
||||
import { SessionProvider } from "next-auth/react"
|
||||
|
||||
export default function App({
|
||||
Component,
|
||||
pageProps: { session, ...pageProps },
|
||||
}) {
|
||||
return (
|
||||
<SessionProvider session={session}>
|
||||
<Component {...pageProps} />
|
||||
</SessionProvider>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
Instances of `useSession` (more on it in the next section) will then have access to the session data and status. The `<SessionProvider />` also takes care of keeping the session updated and synced between browser tabs and windows. 💪🏽
|
||||
|
||||
<Callout>
|
||||
Check our [client docs](/reference/react/) to learn all the available options for handling sessions on the browser.
|
||||
</Callout>
|
||||
|
||||
### Consuming the session via hooks
|
||||
|
||||
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"
|
||||
|
||||
export default function CamperVanPage() {
|
||||
const { data: session, status } = useSession()
|
||||
const userEmail = session?.user.email;
|
||||
|
||||
if (status === "loading") {
|
||||
return <p>Hang on there...</p>
|
||||
}
|
||||
|
||||
if (status === "authenticated") {
|
||||
return (
|
||||
<>
|
||||
<p>Signed in as {userEmail}</p>
|
||||
<button onClick={() => signOut()}>Sign out</button>
|
||||
<img src="https://cdn.pixabay.com/photo/2017/08/11/19/36/vw-2632486_1280.png" />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<p>Not signed in.</p>
|
||||
<button onClick={() => signIn()}>Sign in</button>
|
||||
</>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
You can use the `useSession` hook from anywhere in your application (e.g. in a header component). Behind the scenes, the hook will connect to the `<SessionProvider />` to read the current user session.
|
||||
|
||||
### Protecting API Routes
|
||||
|
||||
Protecting your custom API Routes (.i.e not allowing a resource to be accessed in case the user is not logged in) is easy! You can use [`getSession()`](/reference/utilities/#getsession) to know whether a session exists or not:
|
||||
|
||||
```ts title="pages/api/movies/list.ts"
|
||||
import { getSession } from "next-auth/react"
|
||||
|
||||
export default async function listMovies(req, res) {
|
||||
const session = await getSession({ req })
|
||||
|
||||
if (session) {
|
||||
res.send({
|
||||
movies: [
|
||||
{ title: "Alien vs Predator", id: 1 },
|
||||
{ title: "Reservoir Dogs", id: 2 },
|
||||
],
|
||||
})
|
||||
} else {
|
||||
res.send({
|
||||
error: "You must sign in to view movies.",
|
||||
})
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 2. Configuring OAuth Provider
|
||||
|
||||
Ok, we have our Next.js app setup with NextAuth, however, if you run the app right now, it won't work as we haven't configured our OAuth provider (**Github**) yet.
|
||||
|
||||
<Callout type="info">
|
||||
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.
|
||||
</Callout>
|
||||
|
||||
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.
|
||||
|
||||
<Image src={creatingOauthAppImg} />
|
||||
|
||||
Log in into **Github**, go to `Settings / Developers / OAuth Apps` and click on "New OAuth App".
|
||||
|
||||
Next you'll be presented with a screen to add details about your new application. Fill in the required fields, but pay extra attention to the **Authorization Callback URL** one:
|
||||
|
||||
<Image src={addingCallbackUrlImg} />
|
||||
|
||||
The callback URL we insert should have the following pattern:
|
||||
|
||||
```
|
||||
[origin]/api/auth/callback/[provider]
|
||||
```
|
||||
|
||||
In this case, given we want to try our authentication working locally on our machine and we're using **Github** as our OAuth provider, it'll be:
|
||||
|
||||
```
|
||||
http://localhost:3000/api/auth/callback/github
|
||||
```
|
||||
|
||||
<Callout type="info">
|
||||
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`.
|
||||
</Callout>
|
||||
|
||||
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:
|
||||
|
||||
<Image src={gettingClientIdSecretImg} />
|
||||
|
||||
The Client ID is always there, a public identifier of your OAuth application within Github. Click on the **Generate a new client Secret** button and should be presented with a new string (which is just a randomized string).
|
||||
|
||||
<Callout type="warning">
|
||||
🔥 Keep both your Client ID and Client Secret secure and never expose them to the public or shared with people outside your organization. With tem a malicious actor could hijack your application and cause you and your user serious problems!
|
||||
</Callout>
|
||||
|
||||
Now let's copy both the Client ID and Client Secret and paste them in an environment file in the root of your project like so:
|
||||
|
||||
```title=".env.local"
|
||||
GITHUB_ID=12345
|
||||
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!
|
||||
|
||||
<Callout type="info">
|
||||
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:
|
||||
|
||||
1. Log in to the provider
|
||||
2. Create create your OAuth application within it
|
||||
3. Set the callback URL
|
||||
4. Get the Client ID and Generate a Client Secret
|
||||
</Callout>
|
||||
|
||||
## 3. Wiring all together
|
||||
|
||||
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"
|
||||
import GithubProvider from "next-auth/providers/github"
|
||||
|
||||
export default NextAuth({
|
||||
providers: [
|
||||
GithubProvider({
|
||||
clientId: process.env.GITHUB_ID,
|
||||
clientSecret: process.env.GITHUB_SECRET,
|
||||
}),
|
||||
],
|
||||
})
|
||||
```
|
||||
|
||||
Great! We're now ready to run our application locally. Start the Next.js app by running on your terminal the following command and navigating to [`http://localhost:3000`](http://localhost:3000):
|
||||
|
||||
```
|
||||
$ npm run next dev
|
||||
```
|
||||
|
||||
You should see the following page:
|
||||
|
||||
<Image src={startAppAndSignInImg} />
|
||||
|
||||
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:
|
||||
|
||||
<Image src={githubAuthCredentials} />
|
||||
|
||||
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:
|
||||
|
||||
<Image src={nextAuthUserLoggedIn} />
|
||||
|
||||
Great! We have completed the whole E2E authentication flow setup so that users can login in our application through Github!
|
||||
|
||||
<Callout type="info">
|
||||
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.
|
||||
</Callout>
|
||||
|
||||
## 4. Deploying to production
|
||||
|
||||
### Configuring different environments
|
||||
|
||||
It's normal to test your application under different environments. Usually you'll have a development environment (when you run the application locally in your machine), a staging environment (for teams members to try the application) and a production environment.
|
||||
|
||||
For each environment, you're going to need to create an OAuth application in your provider respectively, as [we did previously](#2-configuring-oauth-provider), and point the **callback URL** to it.
|
||||
|
||||
For instance in the previous section, we pointed the callback URL to:
|
||||
|
||||
```
|
||||
http://localhost:3000/api/auth/callback/github
|
||||
```
|
||||
|
||||
as we wanted to test our application in the development environment.
|
||||
|
||||
If we were to deploy our app to production, we would need to create again a new **OAuth App** in Github (calling it something like "Van life – prod") and point the **callback URL** to our production domain:
|
||||
|
||||
```
|
||||
https://example.com/api/auth/callback/github
|
||||
```
|
||||
|
||||
Finally, we would need just to point the environment variables we set ( `GITHUB_ID` and `GITHUB_SECRET` ) to the credentials of the OAuth app we want our application to run against.
|
||||
|
||||
### Setting up `NEXTAUTH_URL`
|
||||
|
||||
When deploying your site, **you need to set** the `NEXTAUTH_URL` environment variable to the canonical URL of your website:
|
||||
|
||||
```
|
||||
NEXTAUTH_URL=https://example.com
|
||||
```
|
||||
|
||||
<Callout type="warning">
|
||||
In production, this needs to be set as an environment variable on the service you use to deploy your app.
|
||||
|
||||
To set environment variables on Vercel, you can use the [dashboard](https://vercel.com/dashboard) or the `vercel env pull` [command](https://vercel.com/docs/build-step#development-environment-variables).
|
||||
</Callout>
|
||||
|
||||
For more information please check out our [deployment page](/guides/basics/deployment).
|
||||
@@ -1,13 +0,0 @@
|
||||
{
|
||||
"index": "Introduction",
|
||||
"basics": "Basics",
|
||||
"adapters": "Adapters",
|
||||
"providers": "Providers",
|
||||
"testing": "Testing",
|
||||
"corporate-proxies": "Proxies",
|
||||
"other": "Other",
|
||||
"resources": "Community Resources",
|
||||
"img": {
|
||||
"display": "hidden"
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"creating-a-database-adapter": "Create a Database Adapter",
|
||||
"using-a-database-adapter": "Using a Database Adapter"
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"initialization": "Initialization",
|
||||
"callbacks": "Callbacks",
|
||||
"events": "Events",
|
||||
"pages": "Pages",
|
||||
"securing-pages-and-api-routes": "Securing Pages and API Routes",
|
||||
"overriding-jwt": "Overriding JWT",
|
||||
"refresh-token-rotation": "Refresh Token Rotation",
|
||||
"role-based-login-strategy": "Role-Based Access Control",
|
||||
"deployment": "Deployment"
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
---
|
||||
title: Role based logins
|
||||
---
|
||||
|
||||
To add role based authentication to your application, you must do three things.
|
||||
|
||||
1. Update your database schema
|
||||
2. Add the `role` to the session object
|
||||
3. Check for `role` in your pages/components
|
||||
|
||||
First modify the `user` table and add a `role` column with the type of `String?`.
|
||||
|
||||
Below is an example Prisma schema file.
|
||||
|
||||
```javascript title="/prisma/schema.prisma"
|
||||
model User {
|
||||
id String @id @default(cuid())
|
||||
name String?
|
||||
email String? @unique
|
||||
emailVerified DateTime?
|
||||
image String?
|
||||
role String? // New Column
|
||||
accounts Account[]
|
||||
sessions Session[]
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Next, implement a custom session callback in the `[...nextauth].js` file, as shown below.
|
||||
|
||||
```javascript title="/pages/api/auth/[...nextauth].js"
|
||||
callbacks: {
|
||||
async session({ session, token, user }) {
|
||||
session.user.role = user.role; // Add role value to user object so it is passed along with session
|
||||
return session;
|
||||
},
|
||||
```
|
||||
|
||||
Going forward, when using the `getSession` hook, check that `session.user.role` matches the required role. The example below assumes the role `'admin'` is required.
|
||||
|
||||
```javascript title="/pages/admin.js"
|
||||
import { getSession } from "next-auth/react"
|
||||
|
||||
export default function Page() {
|
||||
const session = await getSession({ req })
|
||||
|
||||
if (session && session.user.role === "admin") {
|
||||
return (
|
||||
<div>
|
||||
<h1>Admin</h1>
|
||||
<p>Welcome to the Admin Portal!</p>
|
||||
</div>
|
||||
)
|
||||
} else {
|
||||
return (
|
||||
<div>
|
||||
<h1>You are not authorized to view this page!</h1>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Then it is up to you how you manage your roles, either through direct database access or building your own role update API.
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"avoid-corporate-link-checking-email-provider": "Email Provider Corporate Proxy Compatibility",
|
||||
"corporate-proxy": "Corporate Proxies"
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
---
|
||||
title: Overview
|
||||
sidebar_label: Guides
|
||||
sidebar_position: 0
|
||||
---
|
||||
|
||||
We're creating internal guides to help understand how to use Auth.js and all the possible configurations and uses cases it supports.
|
||||
|
||||
If you can't find what you're looking for, [raise an issue](https://github.com/nextauthjs/next-auth/issues/new/choose) then take a look at our third-party [community resources](/guides/resources).
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"ldap-auth": "LDAP Auth",
|
||||
"usage-with-class-components": "Usage with Class Components"
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
---
|
||||
title: LDAP Authentication
|
||||
---
|
||||
|
||||
Auth.js provides the ability to setup a [custom Credential provider](/guides/providers/credentials) which we can take advantage of to authenticate users against an existing LDAP server.
|
||||
|
||||
You will need an additional dependency, `ldapjs`, which you can install by running
|
||||
|
||||
```bash npm2yarn2pnpm
|
||||
npm install ldapjs
|
||||
```
|
||||
|
||||
Then you must setup the `CredentialsProvider()` provider key like so:
|
||||
|
||||
```js title="[...nextauth].js"
|
||||
const ldap = require("ldapjs")
|
||||
import NextAuth from "next-auth"
|
||||
import CredentialsProvider from "next-auth/providers/credentials"
|
||||
|
||||
export default NextAuth({
|
||||
providers: [
|
||||
CredentialsProvider({
|
||||
name: "LDAP",
|
||||
credentials: {
|
||||
username: { label: "DN", type: "text", placeholder: "" },
|
||||
password: { label: "Password", type: "password" },
|
||||
},
|
||||
async authorize(credentials, req) {
|
||||
// You might want to pull this call out so we're not making a new LDAP client on every login attemp
|
||||
const client = ldap.createClient({
|
||||
url: process.env.LDAP_URI,
|
||||
})
|
||||
|
||||
// Essentially promisify the LDAPJS client.bind function
|
||||
return new Promise((resolve, reject) => {
|
||||
client.bind(credentials.username, credentials.password, (error) => {
|
||||
if (error) {
|
||||
console.error("Failed")
|
||||
reject()
|
||||
} else {
|
||||
console.log("Logged in")
|
||||
resolve({
|
||||
username: credentials.username,
|
||||
password: credentials.password,
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
}),
|
||||
],
|
||||
callbacks: {
|
||||
async jwt({ token, user }) {
|
||||
const isSignIn = user ? true : false
|
||||
if (isSignIn) {
|
||||
token.username = user.username
|
||||
token.password = user.password
|
||||
}
|
||||
return token
|
||||
},
|
||||
async session({ session, token }) {
|
||||
return { ...session, user: { username: token.username } }
|
||||
},
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
The idea is that once one is authenticated with the LDAP server, one can pass through both the username/DN and password to the JWT stored in the browser.
|
||||
|
||||
This is then passed back to any API routes and retrieved as such:
|
||||
|
||||
```js title="/pages/api/doLDAPWork.js"
|
||||
token = await jwt.getToken({
|
||||
req,
|
||||
})
|
||||
const { username, password } = token
|
||||
```
|
||||
|
||||
> Thanks to [Winwardo](https://github.com/Winwardo) for the code example
|
||||
@@ -1,60 +0,0 @@
|
||||
---
|
||||
title: Usage with class components
|
||||
---
|
||||
|
||||
If you want to use the [`useSession()`](/reference/react/#usesession) hook in your class components you can do so with the help of a higher order component or with a render prop.
|
||||
|
||||
## Higher Order Component
|
||||
|
||||
```js
|
||||
import { useSession } from "next-auth/react"
|
||||
|
||||
const withSession = (Component) => (props) => {
|
||||
const session = useSession()
|
||||
|
||||
// if the component has a render property, we are good
|
||||
if (Component.prototype.render) {
|
||||
return <Component session={session} {...props} />
|
||||
}
|
||||
|
||||
// if the passed component is a function component, there is no need for this wrapper
|
||||
throw new Error(
|
||||
[
|
||||
"You passed a function component, `withSession` is not needed.",
|
||||
"You can `useSession` directly in your component.",
|
||||
].join("\n")
|
||||
)
|
||||
}
|
||||
|
||||
// Usage
|
||||
class ClassComponent extends React.Component {
|
||||
render() {
|
||||
const { data: session, status } = this.props.session
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
const ClassComponentWithSession = withSession(ClassComponent)
|
||||
```
|
||||
|
||||
## Render Prop
|
||||
|
||||
```js
|
||||
import { useSession } from "next-auth/react"
|
||||
|
||||
const UseSession = ({ children }) => {
|
||||
const session = useSession()
|
||||
return children(session)
|
||||
}
|
||||
|
||||
// Usage
|
||||
class ClassComponent extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<UseSession>
|
||||
{(session) => <pre>{JSON.stringify(session, null, 2)}</pre>}
|
||||
</UseSession>
|
||||
)
|
||||
}
|
||||
}
|
||||
```
|
||||