Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add: with-next-auth-app-router example #180

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# with-next-auth
# with-next-auth-app-router

## 0.1.1

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# Sign In With Farcaster + NextAuth.js Demo

This example app shows how to use Sign In With Farcaster in a Next.js app with a backend API, using [NextAuth.js](https://next-auth.js.org/) for authentication.
This example app shows how to use Sign In With Farcaster in a Next.js app(App router) with a backend API, using [NextAuth.js](https://next-auth.js.org/) for authentication.

## Getting Started

```sh
$ git clone https://github.com/farcasterxyz/auth-monorepo.git && cd auth-monorepo/examples/with-next-auth
$ git clone https://github.com/farcasterxyz/auth-monorepo.git && cd auth-monorepo/examples/with-next-auth-app-router
$ yarn install
$ yarn dev
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { handlers } from "@/auth"

export const { GET, POST } = handlers
20 changes: 20 additions & 0 deletions examples/with-next-auth-app-router/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type { Metadata } from "next";

export const metadata: Metadata = {
title: "with-next-auth-app-router",
description: "Sign In With Farcaster + NextAuth.js Demo",
};

export default function RootLayout({
children,
}: {
children: React.ReactNode;
}): JSX.Element {
return (
<html lang="en">
<body>
{children}
</body>
</html>
);
}
20 changes: 20 additions & 0 deletions examples/with-next-auth-app-router/app/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import Login from "@/components/login"
import { auth } from "@/auth"
import { SessionProvider } from "next-auth/react"

export default async function ClientPage() {
const session = await auth()
if (session?.user) {
session.user = {
id: session.user.id,
name: session.user.name,
image: session.user.image,
}
}

return (
<SessionProvider basePath={"/api/auth"} session={session}>
<Login />
</SessionProvider>
)
}
41 changes: 41 additions & 0 deletions examples/with-next-auth-app-router/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import NextAuth from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";
import { createAppClient, viemConnector } from "@farcaster/auth-client";

export const { handlers, signIn, signOut, auth } = NextAuth({
providers: [
CredentialsProvider({
name: "Sign in with Farcaster",
credentials: {
message: { label: "Message", type: "text", placeholder: "0x0" },
signature: { label: "Signature", type: "text", placeholder: "0x0" },
name: { label: "Name", type: "text", placeholder: "0x0" },
pfp: { label: "Pfp", type: "text", placeholder: "0x0" },
csrfToken: { label: "CSRF Token", type: "text", placeholder: "0x0" },
},
async authorize(credentials) {
const appClient = createAppClient({
ethereum: viemConnector(),
});

const verifyResponse = await appClient.verifySignInMessage({
message: credentials?.message as string,
signature: credentials?.signature as `0x${string}`,
domain: "example.com",
nonce: credentials.csrfToken as string,
});
const { success, fid } = verifyResponse;

if (!success) {
return null;
}

return {
id: fid.toString(),
name: credentials?.name as string,
image: credentials?.pfp as string,
};
},
}),
],
});
139 changes: 139 additions & 0 deletions examples/with-next-auth-app-router/components/login.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
"use client";

import "@farcaster/auth-kit/styles.css";
import Head from "next/head";
import { useSession, signIn, signOut, getCsrfToken } from "next-auth/react";
import {
SignInButton,
AuthKitProvider,
StatusAPIResponse,
} from "@farcaster/auth-kit";
import { useCallback, useState } from "react";

const config = {
relay: "https://relay.farcaster.xyz",
rpcUrl: "https://mainnet.optimism.io",
siweUri: "http://example.com/login",
domain: "example.com",
};

export default function Login() {
return (
<>
<Head>
<title>Farcaster AuthKit + NextAuth Demo</title>
</Head>
<main style={{ fontFamily: "Inter, sans-serif" }}>
<AuthKitProvider config={config}>
<Content />
</AuthKitProvider>
</main>
</>
);
}

function Content() {
const [error, setError] = useState(false);

const getNonce = useCallback(async () => {
console.log("Getting CSRF token...");
const nonce = await getCsrfToken();
console.log("CSRF token:", nonce);
if (!nonce) throw new Error("Unable to generate nonce");
return nonce;
}, []);

const handleSuccess = useCallback(
(res: StatusAPIResponse) => {
console.log("Success response:", res);
signIn("credentials", {
message: res.message,
signature: res.signature,
name: res.username,
pfp: res.pfpUrl,
csrfToken: (res as unknown as any).csrfToken,
redirect: false,
});
},
[]
);

return (
<div>
<div style={{ position: "fixed", top: "12px", right: "12px" }}>
<SignInButton
nonce={getNonce}
onSuccess={handleSuccess}
onError={() => setError(true)}
onSignOut={() => signOut()}
/>
{error && <div>Unable to sign in at this time.</div>}
</div>
<div style={{ paddingTop: "33vh", textAlign: "center" }}>
<h1>@farcaster/auth-kit + NextAuth</h1>
<p>
This example app shows how to use{" "}
<a
href="https://docs.farcaster.xyz/auth-kit/introduction"
target="_blank" rel="noreferrer"
>
Farcaster AuthKit
</a>{" "}
and{" "}
<a href="https://next-auth.js.org/" target="_blank" rel="noreferrer">
NextAuth.js
</a>
.
</p>
<Profile />
<div>
<h2>Run this demo:</h2>
<div
style={{
margin: "0 auto",
padding: "24px",
textAlign: "left",
maxWidth: "640px",
backgroundColor: "#fafafa",
fontFamily: "monospace",
fontSize: "1.25em",
border: "1px solid #eaeaea",
}}
>
git clone https://github.com/farcasterxyz/auth-monorepo.git &&
<br />
cd auth-monorepo/examples/with-next-auth &&
<br />
yarn install &&
<br />
yarn dev
</div>
</div>
</div>
</div>
);
}

function Profile() {
const { data: session } = useSession();

return session ? (
<div style={{ fontFamily: "sans-serif", color: 'black' }}>
<p>Signed in as {session.user?.name}</p>
<p>
<button
type="button"
style={{ padding: "6px 12px", cursor: "pointer" }}
onClick={() => signOut()}
>
Click here to sign out
</button>
</p>
</div>
) : (
<p>
Click the &quot;Sign in with Farcaster&quot; button above, then scan the QR code to
sign in.
</p>
);
}
1 change: 1 addition & 0 deletions examples/with-next-auth-app-router/middleware.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { auth as middleware } from "@/auth"
6 changes: 6 additions & 0 deletions examples/with-next-auth-app-router/next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true
}

module.exports = nextConfig
28 changes: 28 additions & 0 deletions examples/with-next-auth-app-router/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"name": "with-next-auth-app-router",
"version": "0.1.1",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"@farcaster/auth-client": "*",
"@farcaster/auth-kit": "*",
"ethers": "^6.12.0",
"next": "14.0.4",
"next-auth": "^5.0.0-beta.19",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"viem": "^2.0.3"
},
"devDependencies": {
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"eslint-config-next": "14.2.1",
"typescript": "^5"
}
}
40 changes: 40 additions & 0 deletions examples/with-next-auth-app-router/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"paths": {
"@/*": [
"./*"
]
},
"plugins": [
{
"name": "next"
}
]
},
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx",
".next/types/**/*.ts"
],
"exclude": [
"node_modules"
]
}
3 changes: 3 additions & 0 deletions examples/with-next-auth-pages-router/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "next/core-web-vitals"
}
36 changes: 36 additions & 0 deletions examples/with-next-auth-pages-router/.gitignore
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
10 changes: 10 additions & 0 deletions examples/with-next-auth-pages-router/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# with-next-auth-pages-router

## 0.1.1

### Patch Changes

- 62874a0: - support redirectUrl
- remove ethers hard dependency
- Updated dependencies [62874a0]
- @farcaster/auth-kit@0.2.2
11 changes: 11 additions & 0 deletions examples/with-next-auth-pages-router/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Sign In With Farcaster + NextAuth.js Demo

This example app shows how to use Sign In With Farcaster in a Next.js app(Pages router) with a backend API, using [NextAuth.js](https://next-auth.js.org/) for authentication.

## Getting Started

```sh
$ git clone https://github.com/farcasterxyz/auth-monorepo.git && cd auth-monorepo/examples/with-next-auth-pages-router
$ yarn install
$ yarn dev
```
Loading
Loading