├── .eslintrc.json
├── .gitignore
├── .vscode
└── settings.json
├── README.md
├── app
├── Login.tsx
├── ProvidersWrapper.tsx
├── globals.css
├── head.tsx
├── layout.tsx
├── page.module.css
├── page.tsx
└── userCard.tsx
├── next.config.js
├── package-lock.json
├── package.json
├── pages
└── api
│ ├── auth
│ └── [...nextauth].ts
│ └── hello.ts
├── public
├── favicon.ico
└── vercel.svg
└── 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 | .pnpm-debug.log*
27 |
28 | # local env files
29 | .env*.local
30 |
31 | # vercel
32 | .vercel
33 |
34 | # typescript
35 | *.tsbuildinfo
36 | next-env.d.ts
37 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "typescript.tsdk": "node_modules\\typescript\\lib",
3 | "typescript.enablePromptUseWorkspaceTsdk": true
4 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
2 |
3 | ## Getting Started
4 |
5 | First, run the development server:
6 |
7 | ```bash
8 | npm run dev
9 | # or
10 | yarn dev
11 | ```
12 |
13 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
14 |
15 | You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
16 |
17 | [API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.ts`.
18 |
19 | The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
20 |
21 | ## Learn More
22 |
23 | To learn more about Next.js, take a look at the following resources:
24 |
25 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
26 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
27 |
28 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
29 |
30 | ## Deploy on Vercel
31 |
32 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
33 |
34 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
35 |
--------------------------------------------------------------------------------
/app/Login.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 | import { useSession, signIn, signOut } from "next-auth/react";
3 | import { UserCard } from "./userCard";
4 |
5 | export default function Login() {
6 | // get session from nextAuth
7 | const { data: session } = useSession();
8 | console.log(session);
9 | // useSession uses React Context
10 |
11 | // if the user exists -> show a Sign Out button and their information
12 | if(session) {
13 | return (
14 | <>
15 |
16 | {/* Pass session info to server component */}
17 |
18 | >
19 | )
20 | } else {
21 | return (
22 | <>
23 |
24 | >
25 | )
26 | }
27 |
28 | // if a user doesn't exist -> show a Sign In button
29 | }
--------------------------------------------------------------------------------
/app/ProvidersWrapper.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 | import { SessionProvider } from "next-auth/react";
3 |
4 | export default function ProvidersWrapper({
5 | children,
6 | }: {
7 | children: React.ReactNode
8 | }) {
9 | return (
10 |
11 | {children} {/* Our entire app -> has access to NextAuth */}
12 |
13 | )
14 | }
15 |
--------------------------------------------------------------------------------
/app/globals.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | padding: 0;
4 | margin: 0;
5 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
6 | Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
7 | }
8 |
9 | a {
10 | color: inherit;
11 | text-decoration: none;
12 | }
13 |
14 | * {
15 | box-sizing: border-box;
16 | }
17 |
18 | @media (prefers-color-scheme: dark) {
19 | html {
20 | color-scheme: dark;
21 | }
22 | body {
23 | color: white;
24 | background: black;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/head.tsx:
--------------------------------------------------------------------------------
1 | export default function Head() {
2 | return (
3 | <>
4 | Create Next App
5 |
6 |
7 |
8 | >
9 | )
10 | }
11 |
--------------------------------------------------------------------------------
/app/layout.tsx:
--------------------------------------------------------------------------------
1 | import "bootstrap/dist/css/bootstrap.css"
2 | import ProvidersWrapper from './ProvidersWrapper'
3 |
4 | export default function RootLayout({
5 | children,
6 | }: {
7 | children: React.ReactNode
8 | }) {
9 | return (
10 |
11 | {/*
12 | will contain the components returned by the nearest parent
13 | head.tsx. Find out more at https://beta.nextjs.org/docs/api-reference/file-conventions/head
14 | */}
15 |
17 |
18 | {children}
19 |
20 |
21 |
22 | )
23 | }
24 |
--------------------------------------------------------------------------------
/app/page.module.css:
--------------------------------------------------------------------------------
1 | .container {
2 | padding: 0 2rem;
3 | }
4 |
5 | .main {
6 | min-height: 100vh;
7 | padding: 4rem 0;
8 | flex: 1;
9 | display: flex;
10 | flex-direction: column;
11 | justify-content: center;
12 | align-items: center;
13 | }
14 |
15 | .footer {
16 | display: flex;
17 | flex: 1;
18 | padding: 2rem 0;
19 | border-top: 1px solid #eaeaea;
20 | justify-content: center;
21 | align-items: center;
22 | }
23 |
24 | .footer a {
25 | display: flex;
26 | justify-content: center;
27 | align-items: center;
28 | flex-grow: 1;
29 | }
30 |
31 | .title {
32 | margin: 0;
33 | line-height: 1.15;
34 | font-size: 4rem;
35 | font-style: normal;
36 | font-weight: 800;
37 | letter-spacing: -0.025em;
38 | }
39 |
40 | .title a {
41 | text-decoration: none;
42 | color: #0070f3;
43 | }
44 |
45 | .title a:hover,
46 | .title a:focus,
47 | .title a:active {
48 | text-decoration: underline;
49 | }
50 |
51 | .title,
52 | .description {
53 | text-align: center;
54 | }
55 |
56 | .description {
57 | margin: 4rem 0;
58 | line-height: 1.5;
59 | font-size: 1.5rem;
60 | }
61 |
62 | .code {
63 | background: #fafafa;
64 | border-radius: 5px;
65 | padding: 0.75rem;
66 | font-size: 1.1rem;
67 | font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono,
68 | Bitstream Vera Sans Mono, Courier New, monospace;
69 | }
70 |
71 | .grid {
72 | display: flex;
73 | align-items: center;
74 | justify-content: center;
75 | flex-wrap: wrap;
76 | max-width: 1200px;
77 | }
78 |
79 | .card {
80 | margin: 1rem;
81 | padding: 1.5rem;
82 | text-align: left;
83 | color: inherit;
84 | text-decoration: none;
85 | border: 1px solid #eaeaea;
86 | border-radius: 10px;
87 | transition: color 0.15s ease, border-color 0.15s ease;
88 | max-width: 300px;
89 | }
90 |
91 | .card:hover,
92 | .card:focus,
93 | .card:active {
94 | color: #0070f3;
95 | border-color: #0070f3;
96 | }
97 |
98 | .card h2 {
99 | margin: 0 0 1rem 0;
100 | font-size: 1.5rem;
101 | }
102 |
103 | .card p {
104 | margin: 0;
105 | font-size: 1.25rem;
106 | line-height: 1.5;
107 | }
108 |
109 | .logo {
110 | height: 1em;
111 | margin-left: 0.5rem;
112 | }
113 |
114 | @media (max-width: 600px) {
115 | .grid {
116 | width: 100%;
117 | flex-direction: column;
118 | }
119 | }
120 |
121 | @media (prefers-color-scheme: dark) {
122 | .title {
123 | background: linear-gradient(180deg, #ffffff 0%, #aaaaaa 100%);
124 | -webkit-background-clip: text;
125 | -webkit-text-fill-color: transparent;
126 | background-clip: text;
127 | text-fill-color: transparent;
128 | }
129 | .title a {
130 | background: linear-gradient(180deg, #0070f3 0%, #0153af 100%);
131 | -webkit-background-clip: text;
132 | -webkit-text-fill-color: transparent;
133 | background-clip: text;
134 | text-fill-color: transparent;
135 | }
136 | .card,
137 | .footer {
138 | border-color: #222;
139 | }
140 | .code {
141 | background: #111;
142 | }
143 | .logo img {
144 | filter: invert(1);
145 | }
146 | }
147 |
--------------------------------------------------------------------------------
/app/page.tsx:
--------------------------------------------------------------------------------
1 | import Image from 'next/image'
2 | import styles from './page.module.css'
3 | import Login from './Login'
4 |
5 | // localhost:3000
6 |
7 | export default function Home() {
8 | return (
9 |
10 |
Login Website
11 |
12 |
13 | )
14 | }
15 |
--------------------------------------------------------------------------------
/app/userCard.tsx:
--------------------------------------------------------------------------------
1 | import { DefaultSession } from "next-auth";
2 |
3 | // Default Session TYPE
4 |
5 | export function UserCard( { user } : { user: DefaultSession["user"]}) {
6 |
7 | return (
8 |
9 |
10 |
Current Logged In User
11 |
{user?.name}
12 |
{user?.email}
13 |
14 |
15 | )
16 | }
--------------------------------------------------------------------------------
/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | experimental: {
4 | appDir: true,
5 | },
6 | }
7 |
8 | module.exports = nextConfig
9 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "google-auth",
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": "18.11.9",
13 | "@types/react": "18.0.25",
14 | "@types/react-dom": "18.0.9",
15 | "bootstrap": "^5.2.3",
16 | "eslint": "8.28.0",
17 | "eslint-config-next": "13.0.5",
18 | "next": "13.0.5",
19 | "next-auth": "^4.17.0",
20 | "react": "18.2.0",
21 | "react-dom": "18.2.0",
22 | "typescript": "4.9.3"
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/pages/api/auth/[...nextauth].ts:
--------------------------------------------------------------------------------
1 | import NextAuth from "next-auth";
2 | import GoogleProvider from "next-auth/providers/google";
3 |
4 | // Initialize NextAuth
5 |
6 | export default NextAuth({
7 | providers: [
8 | GoogleProvider({
9 | clientId: "6984088107-b74m2a42votop2kk4hrhfosri34r10d3.apps.googleusercontent.com",
10 | clientSecret: "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"
11 | })
12 | ]
13 | })
--------------------------------------------------------------------------------
/pages/api/hello.ts:
--------------------------------------------------------------------------------
1 | // Next.js API route support: https://nextjs.org/docs/api-routes/introduction
2 | import type { NextApiRequest, NextApiResponse } from 'next'
3 |
4 | type Data = {
5 | name: string
6 | }
7 |
8 | export default function handler(
9 | req: NextApiRequest,
10 | res: NextApiResponse
11 | ) {
12 | res.status(200).json({ name: 'John Doe' })
13 | }
14 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coopercodes/Next.js13GoogleAuthentication/2da9dc6a9f36391add9fde1fdaac702bd3e1f11c/public/favicon.ico
--------------------------------------------------------------------------------
/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": true,
8 | "forceConsistentCasingInFileNames": true,
9 | "noEmit": true,
10 | "esModuleInterop": true,
11 | "module": "esnext",
12 | "moduleResolution": "node",
13 | "resolveJsonModule": true,
14 | "isolatedModules": true,
15 | "jsx": "preserve",
16 | "incremental": true,
17 | "plugins": [
18 | {
19 | "name": "next"
20 | }
21 | ]
22 | },
23 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
24 | "exclude": ["node_modules"]
25 | }
26 |
--------------------------------------------------------------------------------