├── .env.local.example ├── .github └── FUNDING.yml ├── .gitignore ├── LICENSE ├── README.md ├── components ├── access-denied.tsx ├── footer.module.css ├── footer.tsx ├── header.module.css ├── header.tsx └── layout.tsx ├── next-env.d.ts ├── package.json ├── pages ├── _app.tsx ├── api-example.tsx ├── api │ ├── auth │ │ └── [...nextauth].ts │ └── examples │ │ ├── jwt.ts │ │ ├── protected.ts │ │ └── session.ts ├── client.tsx ├── index.tsx ├── policy.tsx ├── protected.tsx ├── server.tsx └── styles.css ├── tsconfig.json └── types ├── environment.d.ts ├── next-auth.d.ts └── next.d.ts /.env.local.example: -------------------------------------------------------------------------------- 1 | NEXTAUTH_URL=http://localhost:3000 2 | SECRET= # Linux: `openssl rand -hex 32` or go to https://generate-secret.now.sh/32 3 | 4 | APPLE_ID= 5 | APPLE_TEAM_ID= 6 | APPLE_PRIVATE_KEY= 7 | APPLE_KEY_ID= 8 | 9 | AUTH0_ID= 10 | AUTH0_SECRET= 11 | AUTH0_DOMAIN= 12 | 13 | FACEBOOK_ID= 14 | FACEBOOK_SECRET= 15 | 16 | GITHUB_ID= 17 | GITHUB_SECRET= 18 | 19 | GOOGLE_ID= 20 | GOOGLE_SECRET= 21 | 22 | TWITTER_ID= 23 | TWITTER_SECRET= 24 | 25 | EMAIL_SERVER=smtp://username:password@smtp.example.com.com:587 26 | EMAIL_FROM=NextAuth 27 | 28 | DATABASE_URL=sqlite://localhost/:memory:?synchronize=true -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # https://docs.github.com/en/github/administering-a-repository/displaying-a-sponsor-button-in-your-repository 2 | 3 | open_collective: nextauth 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # TypeScript v1 declaration files 45 | typings/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | 78 | # Next.js build output 79 | .next 80 | 81 | # Nuxt.js build / generate output 82 | .nuxt 83 | dist 84 | 85 | # Gatsby files 86 | .cache/ 87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 88 | # https://nextjs.org/blog/next-9-1#public-directory-support 89 | # public 90 | 91 | # vuepress build output 92 | .vuepress/dist 93 | 94 | # Serverless directories 95 | .serverless/ 96 | 97 | # FuseBox cache 98 | .fusebox/ 99 | 100 | # DynamoDB Local files 101 | .dynamodb/ 102 | 103 | # TernJS port file 104 | .tern-port 105 | 106 | .vercel 107 | .now 108 | .env.local 109 | 110 | .DS_Store 111 | 112 | # Lock files 113 | yarn.lock 114 | package-lock.json -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | ISC License 2 | 3 | Copyright (c) 2018-2021, Iain Collins 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any 6 | purpose with or without fee is hereby granted, provided that the above 7 | copyright notice and this permission notice appear in all copies. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | > We have migrated the primary [`nextauthjs/next-auth-example`](https://github.com/nextauthjs/next-auth-example) repository to **TypeScript** and will be using that as our primary example repository going forward. **This repository is deprecated**. 2 | 3 |

4 |
5 | 6 |

NextAuth.js Typescript TypeScript logo Example App

7 |

8 | Open Source. Full Stack. Own Your Data. 9 |

10 |

11 | 12 | npm 13 | 14 | 15 | Bundle Size 16 | 17 | 18 | Downloads 19 | 20 |

21 |

22 | 23 | ## Overview 24 | 25 | This is an example of how to use the [NextAuth.js](https://next-auth.js.org) library to add authentication to a [Next.js](https://nextjs.org) application with Typescript. 26 | 27 | Check out the TypeScript [documentation](https://next-auth.js.org/getting-started/typescript). 28 | 29 | This example application can be found under [`next-auth-typescript-example.vercel.app`](https://next-auth-typescript-example.vercel.app) 30 | 31 | ### About NextAuth.js 32 | 33 | NextAuth.js is an easy to implement, full-stack (client/server) open source authentication library designed for [Next.js](https://nextjs.org) and [Serverless](https://vercel.com). 34 | 35 | Go to [next-auth.js.org](https://next-auth.js.org) for more information and documentation. 36 | 37 | > _NextAuth.js is not associated with Vercel or Next.js._ 38 | 39 | ## Getting Started 40 | 41 | ### 1. Clone the repository and install dependancies 42 | 43 | ``` 44 | git clone https://github.com/nextauthjs/next-auth-typescript-example.git 45 | cd next-auth-typescript-example 46 | npm install 47 | ``` 48 | 49 | ### 2. Configure your local environment 50 | 51 | Copy the .env.local.example file in this directory to .env.local (which will be ignored by Git): 52 | 53 | ``` 54 | cp .env.local.example .env.local 55 | ``` 56 | 57 | Add details for one or more providers (e.g. Google, Twitter, GitHub, Email, etc). 58 | 59 | #### Database 60 | 61 | 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. 62 | 63 | You **can** skip configuring a database and come back to it later if you want. 64 | 65 | For more information about setting up a database, please check out the following links: 66 | 67 | - Docs: [next-auth.js.org/adapters/overview](https://next-auth.js.org/adapters/overview) 68 | - Adapters Repo: [nextauthjs/adapters](https://github.com/nextauthjs/adapters) 69 | 70 | ### 3. Configure Authentication Providers 71 | 72 | - Review and update options in `pages/api/auth/[...nextauth].js` as needed. 73 | 74 | - 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}`. 75 | 76 | e.g. For Google OAuth you would use: `http://localhost:3000/api/auth/callback/google` 77 | 78 | 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 79 | 80 | - You can also choose to specify an **SMTP server** for passwordless sign in via email. 81 | 82 | ### 4. Start the application 83 | 84 | To run your site locally, use: 85 | 86 | ``` 87 | npm run dev 88 | ``` 89 | 90 | To run it it production mode, use: 91 | 92 | ``` 93 | npm build 94 | npm start 95 | ``` 96 | 97 | ### 5. Preparing for Production 98 | 99 | You must set the `NEXTAUTH_URL` environment variable with the URL of your site, before deploying to production. 100 | 101 | e.g. in your `.env.local` file - `NEXTAUTH_URL=https://example.com` 102 | 103 | To do this with Vercel, you can use the [Vercel project dashboard](https://vercel.com/dashboard) or their cli with the `vc env` command: 104 | 105 | ``` 106 | vc env add NEXTAUTH_URL production 107 | ``` 108 | 109 | Do not forget to set the environment variables for the Client ID and Client Secret values for all your configured authentication providers in your hosting providers dashboard, i.e. with Vercel as described above. 110 | 111 | ## Acknowledgements 112 | 113 | 114 | Powered By Vercel 115 | 116 |

Thanks to Vercel sponsoring this project by allowing it to be deployed for free for the entire NextAuth.js Team

117 | 118 | ## License 119 | 120 | ISC 121 | -------------------------------------------------------------------------------- /components/access-denied.tsx: -------------------------------------------------------------------------------- 1 | import { signIn } from 'next-auth/react' 2 | 3 | export default function AccessDenied () { 4 | return ( 5 | <> 6 |

Access Denied

7 |

8 | { 10 | e.preventDefault() 11 | signIn() 12 | }}>You must be signed in to view this page 13 |

14 | 15 | ) 16 | } 17 | -------------------------------------------------------------------------------- /components/footer.module.css: -------------------------------------------------------------------------------- 1 | .footer { 2 | margin-top: 2rem; 3 | } 4 | 5 | .navItems { 6 | margin-bottom: 1rem; 7 | padding: 0; 8 | list-style: none; 9 | } 10 | 11 | .navItem { 12 | display: inline-block; 13 | margin-right: 1rem; 14 | } -------------------------------------------------------------------------------- /components/footer.tsx: -------------------------------------------------------------------------------- 1 | import Link from "next/link" 2 | import styles from "./footer.module.css" 3 | import packageInfo from "../package.json" 4 | 5 | export default function Footer() { 6 | return ( 7 | 29 | ) 30 | } 31 | -------------------------------------------------------------------------------- /components/header.module.css: -------------------------------------------------------------------------------- 1 | /* Set min-height to avoid page reflow while session loading */ 2 | .signedInStatus { 3 | display: block; 4 | min-height: 4rem; 5 | width: 100%; 6 | } 7 | 8 | .loading, 9 | .loaded { 10 | position: relative; 11 | top: 0; 12 | opacity: 1; 13 | overflow: hidden; 14 | border-radius: 0 0 .6rem .6rem; 15 | padding: .6rem 1rem; 16 | margin: 0; 17 | background-color: rgba(0,0,0,.05); 18 | transition: all 0.2s ease-in; 19 | } 20 | 21 | .loading { 22 | top: -2rem; 23 | opacity: 0; 24 | } 25 | 26 | .signedInText, 27 | .notSignedInText { 28 | position: absolute; 29 | padding-top: .8rem; 30 | left: 1rem; 31 | right: 6.5rem; 32 | white-space: nowrap; 33 | text-overflow: ellipsis; 34 | overflow: hidden; 35 | display: inherit; 36 | z-index: 1; 37 | line-height: 1.3rem; 38 | } 39 | 40 | .signedInText { 41 | padding-top: 0rem; 42 | left: 4.6rem; 43 | } 44 | 45 | .avatar { 46 | border-radius: 2rem; 47 | float: left; 48 | height: 2.8rem; 49 | width: 2.8rem; 50 | background-color: white; 51 | background-size: cover; 52 | background-repeat: no-repeat; 53 | } 54 | 55 | .button, 56 | .buttonPrimary { 57 | float: right; 58 | margin-right: -.4rem; 59 | font-weight: 500; 60 | border-radius: .3rem; 61 | cursor: pointer; 62 | font-size: 1rem; 63 | line-height: 1.4rem; 64 | padding: .7rem .8rem; 65 | position: relative; 66 | z-index: 10; 67 | background-color: transparent; 68 | color: #555; 69 | } 70 | 71 | .buttonPrimary { 72 | background-color: #346df1; 73 | border-color: #346df1; 74 | color: #fff; 75 | text-decoration: none; 76 | padding: .7rem 1.4rem; 77 | } 78 | 79 | .buttonPrimary:hover { 80 | box-shadow: inset 0 0 5rem rgba(0,0,0,0.2) 81 | } 82 | 83 | .navItems { 84 | margin-bottom: 2rem; 85 | padding: 0; 86 | list-style: none; 87 | } 88 | 89 | .navItem { 90 | display: inline-block; 91 | margin-right: 1rem; 92 | } -------------------------------------------------------------------------------- /components/header.tsx: -------------------------------------------------------------------------------- 1 | import Link from "next/link" 2 | import { signIn, signOut, useSession } from "next-auth/react" 3 | import styles from "./header.module.css" 4 | 5 | // The approach used in this component shows how to built a sign in and sign out 6 | // component that works on pages which support both client and server side 7 | // rendering, and avoids any flash incorrect content on initial page load. 8 | export default function Header() { 9 | const { data: session, status } = useSession() 10 | const loading = status === 'loading' 11 | 12 | return ( 13 |
14 | 17 |
18 |

23 | {!session && ( 24 | <> 25 | 26 | You are not signed in 27 | 28 | { 32 | e.preventDefault() 33 | signIn() 34 | }} 35 | > 36 | Sign in 37 | 38 | 39 | )} 40 | {session?.user && ( 41 | <> 42 | 46 | 47 | Signed in as 48 |
49 | {session.user.email || session.user.name} 50 |
51 | { 55 | e.preventDefault() 56 | signOut() 57 | }} 58 | > 59 | Sign out 60 | 61 | 62 | )} 63 |

64 |
65 | 94 |
95 | ) 96 | } 97 | -------------------------------------------------------------------------------- /components/layout.tsx: -------------------------------------------------------------------------------- 1 | import Header from "./header" 2 | import Footer from "./footer" 3 | 4 | interface LayoutProps { 5 | children: React.ReactNode 6 | } 7 | 8 | export default function Layout({ children }: LayoutProps) { 9 | return ( 10 | <> 11 |
12 |
{children}
13 |