-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: bootstrap nextjs app example project
- Loading branch information
1 parent
57d9b30
commit 69a3639
Showing
24 changed files
with
9,998 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# Use openssl rand -base64 33 to generate a secret | ||
AUTH_SECRET=secret | ||
|
||
AUTH_CLIENT_ID= | ||
AUTH_CLIENT_SECRET= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"extends": "next/core-web-vitals" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. | ||
|
||
# dependencies | ||
/node_modules | ||
/.pnp | ||
.pnp.js | ||
.yarn/install-state.gz | ||
|
||
# testing | ||
/coverage | ||
|
||
# next.js | ||
/.next/ | ||
/out/ | ||
|
||
# production | ||
/build | ||
|
||
# misc | ||
.DS_Store | ||
*.pem | ||
|
||
# debug | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
|
||
# local env files | ||
.env*.local | ||
|
||
# vercel | ||
.vercel | ||
|
||
# typescript | ||
*.tsbuildinfo | ||
next-env.d.ts |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
# React SPA (Single Page App) using Authorization Code Flow with PKCE | ||
|
||
This project demonstrates how to implement the Authorization Code Flow with PKCE for a Next.js App. | ||
|
||
Disclaimer: This project is for educational purposes only and should not be used in production without proper security review and testing. | ||
|
||
## Deployment | ||
|
||
This project is deployed on Cloudflare Pages. You can access the live demo [here](https://cerberauth-nextjs-app-oidc.pages.dev/). | ||
|
||
## Prerequisites | ||
|
||
Before getting started, make sure you have the following: | ||
|
||
- Node.js installed on your machine | ||
- An OpenID Connect provider that supports the Authorization Code Flow with PKCE | ||
|
||
## Getting Started | ||
|
||
1. Clone the repository: | ||
|
||
```bash | ||
git clone https://github.com/cerberauth/openid-connect-examples.git | ||
``` | ||
|
||
2. Install the dependencies: | ||
|
||
```bash | ||
cd openid-connect-examples/nextjs-app | ||
npm ci | ||
``` | ||
|
||
3. Configure the OpenID Connect provider: | ||
|
||
If you don't have an OpenID Connect provider, you can use [TestID OpenID Connect Provider](https://testid.cerberauth.com/). | ||
|
||
- Obtain the client ID and client secret from your OpenID Connect provider. | ||
- Register the redirect URI for your React SPA in the provider's developer console. | ||
|
||
4. Update the configuration: | ||
|
||
- Create a `.env.local` file in the root directory of your project or copy `.env.example` file. | ||
- Add the necessary environment variables to the `.env.local` file. For example: | ||
|
||
```plaintext | ||
AUTH_SECRET=secret | ||
AUTH_CLIENT_ID=your-client-id | ||
AUTH_CLIENT_SECRET=your-client-secret | ||
``` | ||
Generate a random secret using the following command: | ||
```bash | ||
openssl rand -base64 33 | ||
``` | ||
Replace `secret` with the generated secret. | ||
Replace `your-client-id` and `your-client-secret` with the actual values provided by your OpenID Connect provider. | ||
- Save the `.env.local` file. | ||
5. Start the development server: | ||
```bash | ||
npm run dev | ||
``` | ||
|
||
6. Open your browser and navigate to `http://localhost:5173/`. | ||
|
||
7. Click on the "Login" button to initiate the authorization code flow. | ||
|
||
8. After successful authentication, you will be redirected back to the React SPA and the user information will be displayed. | ||
|
||
## Additional Resources | ||
|
||
- [Auth.js](https://authjs.dev/) | ||
- [OpenID Connect](https://openid.net/) | ||
- [OAuth 2.0 Authorization Code Flow](https://oauth.net/2/grant-types/authorization-code/) | ||
- [PKCE](https://oauth.net/2/pkce/) | ||
- [Awesome OpenID Connect](https://github.com/cerberauth/awesome-openid-connect) | ||
- [React](https://reactjs.org/) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
import { handlers } from '@/auth' | ||
|
||
export const runtime = 'edge' | ||
export const { GET, POST } = handlers |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
@tailwind base; | ||
@tailwind components; | ||
@tailwind utilities; | ||
|
||
@layer base { | ||
:root { | ||
--background: 0 0% 100%; | ||
--foreground: 222.2 84% 4.9%; | ||
--card: 0 0% 100%; | ||
--card-foreground: 222.2 84% 4.9%; | ||
--popover: 0 0% 100%; | ||
--popover-foreground: 222.2 84% 4.9%; | ||
--primary: 222.2 47.4% 11.2%; | ||
--primary-foreground: 210 40% 98%; | ||
--secondary: 210 40% 96.1%; | ||
--secondary-foreground: 222.2 47.4% 11.2%; | ||
--muted: 210 40% 96.1%; | ||
--muted-foreground: 215.4 16.3% 46.9%; | ||
--accent: 210 40% 96.1%; | ||
--accent-foreground: 222.2 47.4% 11.2%; | ||
--destructive: 0 84.2% 60.2%; | ||
--destructive-foreground: 210 40% 98%; | ||
--border: 214.3 31.8% 91.4%; | ||
--input: 214.3 31.8% 91.4%; | ||
--ring: 222.2 84% 4.9%; | ||
--radius: 0.5rem; | ||
--chart-1: 12 76% 61%; | ||
--chart-2: 173 58% 39%; | ||
--chart-3: 197 37% 24%; | ||
--chart-4: 43 74% 66%; | ||
--chart-5: 27 87% 67%; | ||
} | ||
|
||
.dark { | ||
--background: 222.2 84% 4.9%; | ||
--foreground: 210 40% 98%; | ||
--card: 222.2 84% 4.9%; | ||
--card-foreground: 210 40% 98%; | ||
--popover: 222.2 84% 4.9%; | ||
--popover-foreground: 210 40% 98%; | ||
--primary: 210 40% 98%; | ||
--primary-foreground: 222.2 47.4% 11.2%; | ||
--secondary: 217.2 32.6% 17.5%; | ||
--secondary-foreground: 210 40% 98%; | ||
--muted: 217.2 32.6% 17.5%; | ||
--muted-foreground: 215 20.2% 65.1%; | ||
--accent: 217.2 32.6% 17.5%; | ||
--accent-foreground: 210 40% 98%; | ||
--destructive: 0 62.8% 30.6%; | ||
--destructive-foreground: 210 40% 98%; | ||
--border: 217.2 32.6% 17.5%; | ||
--input: 217.2 32.6% 17.5%; | ||
--ring: 212.7 26.8% 83.9%; | ||
--chart-1: 220 70% 50%; | ||
--chart-2: 160 60% 45%; | ||
--chart-3: 30 80% 55%; | ||
--chart-4: 280 65% 60%; | ||
--chart-5: 340 75% 55%; | ||
} | ||
} | ||
|
||
@layer base { | ||
* { | ||
@apply border-border; | ||
} | ||
body { | ||
@apply bg-background text-foreground; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import type { Metadata } from 'next' | ||
import { Inter as FontSans } from 'next/font/google' | ||
import { SessionProvider } from 'next-auth/react' | ||
import './globals.css' | ||
|
||
import { cn } from '@/lib/utils' | ||
|
||
const fontSans = FontSans({ | ||
subsets: ['latin'], | ||
variable: '--font-sans', | ||
}) | ||
|
||
export const metadata: Metadata = { | ||
title: 'Next.js Application Example using OpenID Connect', | ||
description: 'This example demonstrates how to authenticate users in a Next.js Application using OpenID Connect Protocol.', | ||
} | ||
|
||
export default function RootLayout({ | ||
children, | ||
}: Readonly<{ | ||
children: React.ReactNode; | ||
}>) { | ||
return ( | ||
<html lang="en"> | ||
<body className={cn( | ||
"bg-slate-100 min-h-screen font-sans antialiased", | ||
fontSans.variable, | ||
)}> | ||
<SessionProvider> | ||
{children} | ||
</SessionProvider> | ||
</body> | ||
</html> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
'use client' | ||
|
||
import { useSession, signOut, signIn } from 'next-auth/react' | ||
import { Button } from '@/components/ui/button' | ||
|
||
export default function Home() { | ||
const session = useSession() | ||
const user = session.data?.user | ||
const isAuthenticated = !!user | ||
|
||
return ( | ||
<div className="bg-slate-100 min-h-screen"> | ||
<main role="main" className="flex flex-col items-center justify-center h-5/6 space-y-8 text-center px-4 py-16 lg:pt-32 md:pt-16 sm:pt-8"> | ||
<h1 className="mt-4 text-2xl font-extrabold tracking-tight text-slate-900 sm:text-5xl xl:max-w-[43.5rem]"> | ||
Next.js Application Example using OpenID Connect | ||
</h1> | ||
<p className="mt-4 max-w-lg text-lg text-slate-700"> | ||
This example demonstrates how to authenticate users in a Next.js Application using OpenID Connect Protocol. | ||
</p> | ||
{isAuthenticated ? ( | ||
<Button onClick={() => signOut()}> | ||
Logout | ||
</Button> | ||
) : ( | ||
<Button onClick={() => signIn('testid')}> | ||
Login with TestID | ||
</Button> | ||
)} | ||
<p className="mt-4 max-w-lg text-slate-700"> | ||
If you want to checkout out how to implement OpenID Connect in your Next.js app, take a look at the <a className="text-indigo-600" href="https://github.com/cerberauth/openid-connect-examples/tree/main/examples/nextjs-app">source code</a>. | ||
</p> | ||
</main> | ||
|
||
<footer className="text-center py-4"> | ||
<p className="text-sm text-gray-500"> | ||
Proudly part of <a className="text-indigo-600" href="https://www.cerberauth.com">CerberAuth</a> community. | ||
</p> | ||
</footer> | ||
</div> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import NextAuth from 'next-auth' | ||
|
||
export const { handlers, signIn, signOut, auth } = NextAuth({ | ||
providers: [{ | ||
id: 'testid', | ||
name: 'TestID', | ||
issuer: 'https://testid.cerberauth.com', | ||
type: 'oidc', | ||
clientId: process.env.AUTH_CLIENT_ID, | ||
clientSecret: process.env.AUTH_CLIENT_SECRET, | ||
checks: ['pkce', 'state'], | ||
authorization: { | ||
params: { scope: 'openid profile email' } | ||
}, | ||
}], | ||
session: { strategy: 'jwt' }, | ||
callbacks: { | ||
session: async ({ session }) => { | ||
return session | ||
}, | ||
} | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{ | ||
"$schema": "https://ui.shadcn.com/schema.json", | ||
"style": "default", | ||
"rsc": true, | ||
"tsx": true, | ||
"tailwind": { | ||
"config": "tailwind.config.ts", | ||
"css": "app/globals.css", | ||
"baseColor": "slate", | ||
"cssVariables": true, | ||
"prefix": "" | ||
}, | ||
"aliases": { | ||
"components": "@/components", | ||
"utils": "@/lib/utils" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import * as React from "react" | ||
import { Slot } from "@radix-ui/react-slot" | ||
import { cva, type VariantProps } from "class-variance-authority" | ||
|
||
import { cn } from "@/lib/utils" | ||
|
||
const buttonVariants = cva( | ||
"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50", | ||
{ | ||
variants: { | ||
variant: { | ||
default: "bg-primary text-primary-foreground hover:bg-primary/90", | ||
destructive: | ||
"bg-destructive text-destructive-foreground hover:bg-destructive/90", | ||
outline: | ||
"border border-input bg-background hover:bg-accent hover:text-accent-foreground", | ||
secondary: | ||
"bg-secondary text-secondary-foreground hover:bg-secondary/80", | ||
ghost: "hover:bg-accent hover:text-accent-foreground", | ||
link: "text-primary underline-offset-4 hover:underline", | ||
}, | ||
size: { | ||
default: "h-10 px-4 py-2", | ||
sm: "h-9 rounded-md px-3", | ||
lg: "h-11 rounded-md px-8", | ||
icon: "h-10 w-10", | ||
}, | ||
}, | ||
defaultVariants: { | ||
variant: "default", | ||
size: "default", | ||
}, | ||
} | ||
) | ||
|
||
export interface ButtonProps | ||
extends React.ButtonHTMLAttributes<HTMLButtonElement>, | ||
VariantProps<typeof buttonVariants> { | ||
asChild?: boolean | ||
} | ||
|
||
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>( | ||
({ className, variant, size, asChild = false, ...props }, ref) => { | ||
const Comp = asChild ? Slot : "button" | ||
return ( | ||
<Comp | ||
className={cn(buttonVariants({ variant, size, className }))} | ||
ref={ref} | ||
{...props} | ||
/> | ||
) | ||
} | ||
) | ||
Button.displayName = "Button" | ||
|
||
export { Button, buttonVariants } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import { type ClassValue, clsx } from "clsx" | ||
import { twMerge } from "tailwind-merge" | ||
|
||
export function cn(...inputs: ClassValue[]) { | ||
return twMerge(clsx(inputs)) | ||
} |
Oops, something went wrong.