├── .eslintrc.json
├── .gitignore
├── README.md
├── next.config.js
├── package-lock.json
├── package.json
├── postcss.config.js
├── public
├── next.svg
└── vercel.svg
├── src
├── app
│ ├── api
│ │ └── auth
│ │ │ └── [...nextauth]
│ │ │ ├── options.ts
│ │ │ └── route.ts
│ ├── client
│ │ └── page.tsx
│ ├── components
│ │ ├── Navbar.tsx
│ │ └── UserCard.tsx
│ ├── context
│ │ └── AuthProvider.tsx
│ ├── extra
│ │ └── page.tsx
│ ├── favicon.ico
│ ├── globals.css
│ ├── layout.tsx
│ ├── page.tsx
│ └── server
│ │ └── page.tsx
└── middleware.ts
├── tailwind.config.js
└── tsconfig.json
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "next/core-web-vitals"
3 | }
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 | *.pem
21 |
22 | # debug
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 |
27 | # local env files
28 | .env*.local
29 |
30 | # vercel
31 | .vercel
32 |
33 | # typescript
34 | *.tsbuildinfo
35 | next-env.d.ts
36 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # "NextAuth.js Login Authentication"
2 |
3 | ## With Next.js App Router
4 |
5 | ---
6 |
7 | ### Author Links
8 |
9 | 👋 Hello, I'm Dave Gray.
10 |
11 | 👉 [My Courses](https://courses.davegray.codes/)
12 |
13 | ✅ [Check out my YouTube Channel with hundreds of tutorials](https://www.youtube.com/DaveGrayTeachesCode).
14 |
15 | 🚩 [Subscribe to my channel](https://bit.ly/3nGHmNn)
16 |
17 | ☕ [Buy Me A Coffee](https://buymeacoffee.com/DaveGray)
18 |
19 | 🚀 Follow Me:
20 |
21 | - [Twitter](https://twitter.com/yesdavidgray)
22 | - [LinkedIn](https://www.linkedin.com/in/davidagray/)
23 | - [Blog](https://yesdavidgray.com)
24 | - [Reddit](https://www.reddit.com/user/DaveOnEleven)
25 |
26 | ---
27 |
28 | ### Description
29 |
30 | 📺 [YouTube Video](https://youtu.be/w2h54xz6Ndw) for this repository.
31 |
32 | ---
33 |
34 | ### 🎓 Academic Honesty
35 |
36 | **DO NOT COPY FOR AN ASSIGNMENT** - Avoid plagiarism and adhere to the spirit of this [Academic Honesty Policy](https://www.freecodecamp.org/news/academic-honesty-policy/).
37 |
38 | ---
39 |
40 | ### ⚙ Free Web Dev Tools
41 | - 🔗 [Google Chrome Web Browser](https://google.com/chrome/)
42 | - 🔗 [Visual Studio Code (aka VS Code)](https://code.visualstudio.com/)
43 | - 🔗 [ES7 React Snippets](https://marketplace.visualstudio.com/items?itemName=dsznajder.es7-react-js-snippets)
44 |
45 | ### 📚 References
46 | - 🔗 [NextAuth.js Official Site](https://next-auth.js.org/)
47 | - 🔗 [Next.js Official Site](https://nextjs.org/)
48 |
49 |
50 |
--------------------------------------------------------------------------------
/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | images: {
4 | remotePatterns: [
5 | {
6 | protocol: 'https',
7 | hostname: 'avatars.githubusercontent.com',
8 | port: '',
9 | pathname: '/u/**',
10 | },
11 | ],
12 | },
13 | }
14 |
15 | module.exports = nextConfig
16 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "next-auth-tut",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start",
9 | "lint": "next lint"
10 | },
11 | "dependencies": {
12 | "@types/node": "20.3.2",
13 | "@types/react": "18.2.14",
14 | "@types/react-dom": "18.2.6",
15 | "autoprefixer": "10.4.14",
16 | "eslint": "8.43.0",
17 | "eslint-config-next": "13.4.7",
18 | "next": "13.4.7",
19 | "next-auth": "^4.22.1",
20 | "postcss": "8.4.24",
21 | "react": "18.2.0",
22 | "react-dom": "18.2.0",
23 | "tailwindcss": "3.3.2",
24 | "typescript": "5.1.6"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/public/next.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/app/api/auth/[...nextauth]/options.ts:
--------------------------------------------------------------------------------
1 | import type { NextAuthOptions } from 'next-auth'
2 | import GitHubProvider from 'next-auth/providers/github'
3 | import CredentialsProvider from 'next-auth/providers/credentials'
4 |
5 | export const options: NextAuthOptions = {
6 | providers: [
7 | GitHubProvider({
8 | clientId: process.env.GITHUB_ID as string,
9 | clientSecret: process.env.GITHUB_SECRET as string,
10 | }),
11 | CredentialsProvider({
12 | name: "Credentials",
13 | credentials: {
14 | username: {
15 | label: "Username:",
16 | type: "text",
17 | placeholder: "your-cool-username"
18 | },
19 | password: {
20 | label: "Password:",
21 | type: "password",
22 | placeholder: "your-awesome-password"
23 | }
24 | },
25 | async authorize(credentials) {
26 | // This is where you need to retrieve user data
27 | // to verify with credentials
28 | // Docs: https://next-auth.js.org/configuration/providers/credentials
29 | const user = { id: "42", name: "Dave", password: "nextauth" }
30 |
31 | if (credentials?.username === user.name && credentials?.password === user.password) {
32 | return user
33 | } else {
34 | return null
35 | }
36 | }
37 | })
38 | ],
39 | }
--------------------------------------------------------------------------------
/src/app/api/auth/[...nextauth]/route.ts:
--------------------------------------------------------------------------------
1 | import NextAuth from 'next-auth'
2 | import { options } from './options'
3 |
4 | const handler = NextAuth(options)
5 |
6 | export { handler as GET, handler as POST }
--------------------------------------------------------------------------------
/src/app/client/page.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 | // Remember you must use an AuthProvider for
3 | // client components to useSession
4 | import { useSession } from 'next-auth/react'
5 | import { redirect } from 'next/navigation'
6 | import UserCard from '../components/UserCard'
7 |
8 | export default function ClientPage() {
9 | const { data: session } = useSession({
10 | required: true,
11 | onUnauthenticated() {
12 | redirect('/api/auth/signin?callbackUrl=/client')
13 | }
14 | })
15 |
16 | return (
17 |
{pagetype} Page!
47 |