diff --git a/.env.local.example b/.env.local.example
new file mode 100644
index 0000000..0230c5f
--- /dev/null
+++ b/.env.local.example
@@ -0,0 +1,28 @@
+NEXTAUTH_URL=http://localhost:3000
+NEXTAUTH_SECRET= # Linux: `openssl rand -hex 32` or go to https://generate-secret.now.sh/32
+
+APPLE_ID=
+APPLE_TEAM_ID=
+APPLE_PRIVATE_KEY=
+APPLE_KEY_ID=
+
+AUTH0_ID=
+AUTH0_SECRET=
+AUTH0_ISSUER=
+
+FACEBOOK_ID=
+FACEBOOK_SECRET=
+
+GITHUB_ID=
+GITHUB_SECRET=
+
+GOOGLE_ID=
+GOOGLE_SECRET=
+
+TWITTER_ID=
+TWITTER_SECRET=
+
+EMAIL_SERVER=smtp://username:password@smtp.example.com:587
+EMAIL_FROM=NextAuth
+
+DATABASE_URL=sqlite://localhost/:memory:?synchronize=true
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 0000000..63f8770
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,4 @@
+# https://docs.github.com/en/github/administering-a-repository/displaying-a-sponsor-button-in-your-repository
+
+open_collective: nextauth
+github: [balazsorban44]
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e6b58d6
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,20 @@
+.DS_Store
+
+node_modules/
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+lerna-debug.log*
+.yarn-integrity
+.npm
+
+.eslintcache
+
+*.tsbuildinfo
+next-env.d.ts
+
+.next
+.vercel
+.env*.local
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..eee418e
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,15 @@
+ISC License
+
+Copyright (c) 2018-2021, Iain Collins
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..2e8e934
--- /dev/null
+++ b/README.md
@@ -0,0 +1,113 @@
+> The example repository is maintained from a [monorepo](https://github.com/nextauthjs/next-auth/tree/main/apps/example-nextjs). Pull Requests should be opened against [`nextauthjs/next-auth`](https://github.com/nextauthjs/next-auth).
+
+
+
+## Overview
+
+NextAuth.js is a complete open source authentication solution.
+
+This is an example application that shows how `next-auth` is applied to a basic Next.js app.
+
+The deployed version can be found at [`next-auth-example.vercel.app`](https://next-auth-example.vercel.app)
+
+### About NextAuth.js
+
+NextAuth.js is an easy to implement, full-stack (client/server) open source authentication library originally designed for [Next.js](https://nextjs.org) and [Serverless](https://vercel.com). Our goal is to [support even more frameworks](https://github.com/nextauthjs/next-auth/issues/2294) in the future.
+
+Go to [next-auth.js.org](https://next-auth.js.org) for more information and documentation.
+
+> *NextAuth.js is not officially associated with Vercel or Next.js.*
+
+## Getting Started
+
+### 1. Clone the repository and install dependencies
+
+```
+git clone https://github.com/nextauthjs/next-auth-example.git
+cd next-auth-example
+npm install
+```
+
+### 2. Configure your local environment
+
+Copy the .env.local.example file in this directory to .env.local (which will be ignored by Git):
+
+```
+cp .env.local.example .env.local
+```
+
+Add details for one or more providers (e.g. Google, Twitter, GitHub, Email, etc).
+
+#### Database
+
+A database is needed to persist user accounts and to support email sign in. However, you can still use NextAuth.js for authentication without a database by using OAuth for authentication. If you do not specify a database, [JSON Web Tokens](https://jwt.io/introduction) will be enabled by default.
+
+You **can** skip configuring a database and come back to it later if you want.
+
+For more information about setting up a database, please check out the following links:
+
+* Docs: [next-auth.js.org/adapters/overview](https://next-auth.js.org/adapters/overview)
+
+### 3. Configure Authentication Providers
+
+1. Review and update options in `pages/api/auth/[...nextauth].js` as needed.
+
+2. When setting up OAuth, in the developer admin page for each of your OAuth services, you should configure the callback URL to use a callback path of `{server}/api/auth/callback/{provider}`.
+
+ e.g. For Google OAuth you would use: `http://localhost:3000/api/auth/callback/google`
+
+ A list of configured providers and their callback URLs is available from the endpoint `/api/auth/providers`. You can find more information at https://next-auth.js.org/configuration/providers/oauth
+
+3. You can also choose to specify an SMTP server for passwordless sign in via email.
+
+### 4. Start the application
+
+To run your site locally, use:
+
+```
+npm run dev
+```
+
+To run it in production mode, use:
+
+```
+npm run build
+npm run start
+```
+
+### 5. Preparing for Production
+
+Follow the [Deployment documentation](https://next-auth.js.org/deployment)
+
+## Acknowledgements
+
+
+
+
+
Thanks to Vercel sponsoring this project by allowing it to be deployed for free for the entire NextAuth.js Team
+
+
+ )
+}
diff --git a/components/layout.tsx b/components/layout.tsx
new file mode 100644
index 0000000..9ee0bb2
--- /dev/null
+++ b/components/layout.tsx
@@ -0,0 +1,13 @@
+import Header from "./header"
+import Footer from "./footer"
+import type { ReactNode } from "react"
+
+export default function Layout({ children }: { children: ReactNode }) {
+ return (
+ <>
+
+ {children}
+
+ >
+ )
+}
diff --git a/middleware.ts b/middleware.ts
new file mode 100644
index 0000000..2c628ae
--- /dev/null
+++ b/middleware.ts
@@ -0,0 +1,17 @@
+import { withAuth } from "next-auth/middleware"
+
+// More on how NextAuth.js middleware works: https://next-auth.js.org/configuration/nextjs#middleware
+export default withAuth({
+ callbacks: {
+ authorized({ req, token }) {
+ // `/admin` requires admin role
+ if (req.nextUrl.pathname === "/admin") {
+ return token?.userRole === "admin"
+ }
+ // `/me` only requires the user to be logged in
+ return !!token
+ },
+ },
+})
+
+export const config = { matcher: ["/admin", "/me"] }
diff --git a/next-auth.d.ts b/next-auth.d.ts
new file mode 100644
index 0000000..ce05151
--- /dev/null
+++ b/next-auth.d.ts
@@ -0,0 +1,10 @@
+import "next-auth/jwt"
+
+// Read more at: https://next-auth.js.org/getting-started/typescript#module-augmentation
+
+declare module "next-auth/jwt" {
+ interface JWT {
+ /** The user's role. */
+ userRole?: "admin"
+ }
+}
diff --git a/next-env.d.ts b/next-env.d.ts
new file mode 100644
index 0000000..4f11a03
--- /dev/null
+++ b/next-env.d.ts
@@ -0,0 +1,5 @@
+///
+///
+
+// NOTE: This file should not be edited
+// see https://nextjs.org/docs/basic-features/typescript for more information.
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..1496c3b
--- /dev/null
+++ b/package.json
@@ -0,0 +1,32 @@
+{
+ "private": true,
+ "description": "An example project for NextAuth.js with Next.js",
+ "repository": "https://github.com/nextauthjs/next-auth-example.git",
+ "bugs": {
+ "url": "https://github.com/nextauthjs/next-auth/issues"
+ },
+ "homepage": "https://next-auth-example.vercel.app",
+ "scripts": {
+ "dev": "next",
+ "build": "next build",
+ "start": "next start"
+ },
+ "author": "Iain Collins ",
+ "contributors": [
+ "Balázs Orbán ",
+ "Nico Domino ",
+ "Lluis Agusti "
+ ],
+ "dependencies": {
+ "next": "latest",
+ "next-auth": "latest",
+ "nodemailer": "^6",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0"
+ },
+ "devDependencies": {
+ "@types/node": "^17",
+ "@types/react": "^18.0.37",
+ "typescript": "^4"
+ }
+}
diff --git a/pages/_app.tsx b/pages/_app.tsx
new file mode 100644
index 0000000..035bfdf
--- /dev/null
+++ b/pages/_app.tsx
@@ -0,0 +1,18 @@
+import { SessionProvider } from "next-auth/react"
+import "./styles.css"
+
+import type { AppProps } from "next/app"
+import type { Session } from "next-auth"
+
+// Use of the is mandatory to allow components that call
+// `useSession()` anywhere in your application to access the `session` object.
+export default function App({
+ Component,
+ pageProps: { session, ...pageProps },
+}: AppProps<{ session: Session }>) {
+ return (
+
+
+
+ )
+}
diff --git a/pages/admin.tsx b/pages/admin.tsx
new file mode 100644
index 0000000..40b3515
--- /dev/null
+++ b/pages/admin.tsx
@@ -0,0 +1,17 @@
+import Layout from "../components/layout"
+
+export default function Page() {
+ return (
+
+
This page is protected by Middleware
+
Only admin users can see this page.
+
+ To learn more about the NextAuth middleware see
+
+ the docs
+
+ .
+
+
+ )
+}
diff --git a/pages/api-example.tsx b/pages/api-example.tsx
new file mode 100644
index 0000000..1962311
--- /dev/null
+++ b/pages/api-example.tsx
@@ -0,0 +1,19 @@
+import Layout from "../components/layout"
+
+export default function ApiExamplePage() {
+ return (
+
+
API Example
+
The examples below show responses from the example API endpoints.
+
+ You must be signed in to see responses.
+
+
Session
+
/api/examples/session
+
+
JSON Web Token
+
/api/examples/jwt
+
+
+ )
+}
diff --git a/pages/api/auth/[...nextauth].ts b/pages/api/auth/[...nextauth].ts
new file mode 100644
index 0000000..57d83d4
--- /dev/null
+++ b/pages/api/auth/[...nextauth].ts
@@ -0,0 +1,65 @@
+import NextAuth, { NextAuthOptions } from "next-auth"
+import GoogleProvider from "next-auth/providers/google"
+import FacebookProvider from "next-auth/providers/facebook"
+import GithubProvider from "next-auth/providers/github"
+import TwitterProvider from "next-auth/providers/twitter"
+import Auth0Provider from "next-auth/providers/auth0"
+// import AppleProvider from "next-auth/providers/apple"
+// import EmailProvider from "next-auth/providers/email"
+
+// For more information on each option (and a full list of options) go to
+// https://next-auth.js.org/configuration/options
+export const authOptions: NextAuthOptions = {
+ // https://next-auth.js.org/configuration/providers/oauth
+ providers: [
+ /* EmailProvider({
+ server: process.env.EMAIL_SERVER,
+ from: process.env.EMAIL_FROM,
+ }),
+ // Temporarily removing the Apple provider from the demo site as the
+ // callback URL for it needs updating due to Vercel changing domains
+
+ Providers.Apple({
+ clientId: process.env.APPLE_ID,
+ clientSecret: {
+ appleId: process.env.APPLE_ID,
+ teamId: process.env.APPLE_TEAM_ID,
+ privateKey: process.env.APPLE_PRIVATE_KEY,
+ keyId: process.env.APPLE_KEY_ID,
+ },
+ }),
+ */
+ FacebookProvider({
+ clientId: process.env.FACEBOOK_ID,
+ clientSecret: process.env.FACEBOOK_SECRET,
+ }),
+ GithubProvider({
+ clientId: process.env.GITHUB_ID,
+ clientSecret: process.env.GITHUB_SECRET,
+ }),
+ GoogleProvider({
+ clientId: process.env.GOOGLE_ID,
+ clientSecret: process.env.GOOGLE_SECRET,
+ }),
+ TwitterProvider({
+ clientId: process.env.TWITTER_ID,
+ clientSecret: process.env.TWITTER_SECRET,
+ }),
+ Auth0Provider({
+ clientId: process.env.AUTH0_ID,
+ clientSecret: process.env.AUTH0_SECRET,
+ issuer: process.env.AUTH0_ISSUER,
+ }),
+ ],
+ theme: {
+ colorScheme: "light",
+ },
+ callbacks: {
+ async jwt({ token }) {
+ token.userRole = "admin"
+ return token
+ },
+ },
+}
+
+export default NextAuth(authOptions)
diff --git a/pages/api/examples/jwt.ts b/pages/api/examples/jwt.ts
new file mode 100644
index 0000000..549786c
--- /dev/null
+++ b/pages/api/examples/jwt.ts
@@ -0,0 +1,14 @@
+// This is an example of how to read a JSON Web Token from an API route
+import { getToken } from "next-auth/jwt"
+
+import type { NextApiRequest, NextApiResponse } from "next"
+
+export default async function handler(
+ req: NextApiRequest,
+ res: NextApiResponse
+) {
+ // If you don't have the NEXTAUTH_SECRET environment variable set,
+ // you will have to pass your secret as `secret` to `getToken`
+ const token = await getToken({ req })
+ res.send(JSON.stringify(token, null, 2))
+}
diff --git a/pages/api/examples/protected.ts b/pages/api/examples/protected.ts
new file mode 100644
index 0000000..96db322
--- /dev/null
+++ b/pages/api/examples/protected.ts
@@ -0,0 +1,23 @@
+// This is an example of to protect an API route
+import { getServerSession } from "next-auth/next"
+import { authOptions } from "../auth/[...nextauth]"
+
+import type { NextApiRequest, NextApiResponse } from "next"
+
+export default async function handler(
+ req: NextApiRequest,
+ res: NextApiResponse
+) {
+ const session = await getServerSession(req, res, authOptions)
+
+ if (session) {
+ return res.send({
+ content:
+ "This is protected content. You can access this content because you are signed in.",
+ })
+ }
+
+ res.send({
+ error: "You must be signed in to view the protected content on this page.",
+ })
+}
diff --git a/pages/api/examples/session.ts b/pages/api/examples/session.ts
new file mode 100644
index 0000000..bb7f46e
--- /dev/null
+++ b/pages/api/examples/session.ts
@@ -0,0 +1,13 @@
+// This is an example of how to access a session from an API route
+import { getServerSession } from "next-auth"
+import { authOptions } from "../auth/[...nextauth]"
+
+import type { NextApiRequest, NextApiResponse } from "next"
+
+export default async function handler(
+ req: NextApiRequest,
+ res: NextApiResponse
+) {
+ const session = await getServerSession(req, res, authOptions)
+ res.send(JSON.stringify(session, null, 2))
+}
diff --git a/pages/client.tsx b/pages/client.tsx
new file mode 100644
index 0000000..710a005
--- /dev/null
+++ b/pages/client.tsx
@@ -0,0 +1,27 @@
+import Layout from "../components/layout"
+
+export default function ClientPage() {
+ return (
+
+
Client Side Rendering
+
+ This page uses the useSession() React Hook in the{" "}
+ <Header/> component.
+
+
+ The useSession() React Hook is easy to use and allows
+ pages to render very quickly.
+
+
+ The advantage of this approach is that session state is shared between
+ pages by using the Provider in _app.js{" "}
+ so that navigation between pages using useSession() is
+ very fast.
+
+
+ The disadvantage of useSession() is that it requires
+ client side JavaScript.
+
+
+ )
+}
diff --git a/pages/index.tsx b/pages/index.tsx
new file mode 100644
index 0000000..7b09b8a
--- /dev/null
+++ b/pages/index.tsx
@@ -0,0 +1,13 @@
+import Layout from "../components/layout"
+
+export default function IndexPage() {
+ return (
+
+
NextAuth.js Example
+
+ This is an example site to demonstrate how to use{" "}
+ NextAuth.js for authentication.
+
+
+ )
+}
diff --git a/pages/me.tsx b/pages/me.tsx
new file mode 100644
index 0000000..d7f0214
--- /dev/null
+++ b/pages/me.tsx
@@ -0,0 +1,12 @@
+import { useSession } from "next-auth/react"
+import Layout from "../components/layout"
+
+export default function MePage() {
+ const { data } = useSession()
+
+ return (
+
+
{JSON.stringify(data, null, 2)}
+
+ )
+}
diff --git a/pages/policy.tsx b/pages/policy.tsx
new file mode 100644
index 0000000..21c4ab3
--- /dev/null
+++ b/pages/policy.tsx
@@ -0,0 +1,32 @@
+import Layout from "../components/layout"
+
+export default function PolicyPage() {
+ return (
+
+
+ This is an example site to demonstrate how to use{" "}
+ NextAuth.js for authentication.
+
+
Terms of Service
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
Privacy Policy
+
+ This site uses JSON Web Tokens and an in-memory database which resets
+ every ~2 hours.
+
+
+ Data provided to this site is exclusively used to support signing in and
+ is not passed to any third party services, other than via SMTP or OAuth
+ for the purposes of authentication.
+
+
+ )
+}
diff --git a/pages/server.tsx b/pages/server.tsx
new file mode 100644
index 0000000..d69ce23
--- /dev/null
+++ b/pages/server.tsx
@@ -0,0 +1,43 @@
+import { getServerSession } from "next-auth/next"
+import { authOptions } from "./api/auth/[...nextauth]"
+import Layout from "../components/layout"
+
+import type { GetServerSidePropsContext } from "next"
+import type { Session } from "next-auth"
+
+export default function ServerSidePage({ session }: { session: Session }) {
+ // As this page uses Server Side Rendering, the `session` will be already
+ // populated on render without needing to go through a loading stage.
+ return (
+
+
Server Side Rendering
+
+ This page uses the getServerSession() method in{" "}
+ getServerSideProps().
+
+
+ Using getServerSession() in{" "}
+ getServerSideProps() is the recommended approach if you
+ need to support Server Side Rendering with authentication.
+
+
+ The advantage of Server Side Rendering is this page does not require
+ client side JavaScript.
+
+
+ The disadvantage of Server Side Rendering is that this page is slower to
+ render.
+