Skip to content

Commit f6e2b06

Browse files
Add Supertokens example (#21384)
1 parent 80c9522 commit f6e2b06

File tree

13 files changed

+517
-0
lines changed

13 files changed

+517
-0
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Public Environment variables that can be used in the browser.
2+
NEXT_PUBLIC_APP_URL="http://localhost:3000"
3+
4+
# Secret environment variables only available to Node.js
5+
APP_URL="http://localhost:3000"
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
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+
.env.development.local
30+
.env.test.local
31+
.env.production.local
32+
33+
# vercel
34+
.vercel
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# SuperTokens Example
2+
3+
This is a simple set up for applications protected by SuperTokens.
4+
5+
The SuperTokens back end configurations are in `supertokens.js`.
6+
7+
The SuperTokens front end configurations are in `pages/_app.js`.
8+
9+
## Deploy your own
10+
11+
Deploy the example using [Vercel](https://vercel.com):
12+
13+
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https://github.com/vercel/next.js/tree/canary/examples/with-supertokens&project-name=with-supertokens&repository-name=with-supertokens)
14+
15+
## How to use
16+
17+
Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example:
18+
19+
```bash
20+
npx create-next-app --example with-supertokens with-supertokens-app
21+
# or
22+
yarn create next-app --example with-supertokens with-supertokens-app
23+
```
24+
25+
## Configuration
26+
27+
Create a `.env.local` file and copy the content of `.env.local.example` into it:
28+
29+
```bash
30+
cp .env.local.example .env.local
31+
```
32+
33+
## Deploy on Vercel
34+
35+
You can deploy this app to the cloud with [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)).
36+
37+
### Deploy Your Local Project
38+
39+
To deploy your local project to Vercel, push it to GitHub/GitLab/Bitbucket and [import to Vercel](https://vercel.com/new?utm_source=github&utm_medium=readme&utm_campaign=next-example).
40+
41+
**Important**: When you import your project on Vercel, make sure to click on **Environment Variables** and set them to match your `.env.local` file.
42+
43+
## Notes
44+
45+
Take a look at [SuperTokens documentation](https://supertokens.io/docs/emailpassword/introduction) to configure SuperTokens for your project.
46+
47+
Especially, you will want to replace the use of the demo SuperTokens core with your own SuperTokens core instance. See https://supertokens.io/docs/emailpassword/quick-setup/supertokens-core/overview.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"name": "with-supertokens",
3+
"version": "1.0.0",
4+
"private": true,
5+
"scripts": {
6+
"dev": "next dev",
7+
"build": "next build",
8+
"start": "next start"
9+
},
10+
"dependencies": {
11+
"next": "latest",
12+
"react": "17.0.1",
13+
"react-dom": "17.0.1",
14+
"supertokens-auth-react": "^0.5.1",
15+
"supertokens-node": "^3.4.0"
16+
},
17+
"license": "MIT"
18+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import '../styles/globals.css'
2+
import React from 'react'
3+
import SuperTokensReact from 'supertokens-auth-react'
4+
import EmailPasswordReact from 'supertokens-auth-react/recipe/emailpassword'
5+
import SessionReact from 'supertokens-auth-react/recipe/session'
6+
import SuperTokensNode from 'supertokens-node'
7+
import SessionNode from 'supertokens-node/recipe/session'
8+
import EmailPasswordNode from 'supertokens-node/recipe/emailpassword'
9+
const port = process.env.APP_PORT || 3000
10+
const websiteDomain =
11+
process.env.APP_URL ||
12+
process.env.NEXT_PUBLIC_APP_URL ||
13+
`http://localhost:${port}`
14+
const apiBasePath = '/api/auth/'
15+
16+
// Client Side configs.
17+
if (typeof window !== 'undefined') {
18+
SuperTokensReact.init({
19+
appInfo: {
20+
appName: 'SuperTokens Demo App',
21+
websiteDomain,
22+
apiDomain: websiteDomain,
23+
apiBasePath,
24+
},
25+
recipeList: [
26+
EmailPasswordReact.init({
27+
emailVerificationFeature: {
28+
mode: 'REQUIRED',
29+
},
30+
}),
31+
SessionReact.init(),
32+
],
33+
})
34+
} else {
35+
// Server Side configs.
36+
SuperTokensNode.init({
37+
supertokens: {
38+
connectionURI: 'https://try.supertokens.io', // Replace with your SuperTokens core instance. See https://supertokens.io/docs/emailpassword/quick-setup/supertokens-core/overview
39+
},
40+
appInfo: {
41+
appName: 'SuperTokens Demo App',
42+
websiteDomain,
43+
apiDomain: websiteDomain,
44+
apiBasePath,
45+
},
46+
recipeList: [EmailPasswordNode.init(), SessionNode.init()],
47+
})
48+
}
49+
50+
function MyApp({ Component, pageProps }) {
51+
return <Component {...pageProps} />
52+
}
53+
54+
export default MyApp
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
2+
import { superTokensNextWrapper } from 'supertokens-node/nextjs'
3+
import { middleware } from 'supertokens-node'
4+
5+
export default async function superTokens(req, res) {
6+
return await superTokensNextWrapper(
7+
async (next) => {
8+
await middleware()(req, res, next)
9+
},
10+
req,
11+
res
12+
)
13+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
2+
import { superTokensNextWrapper } from 'supertokens-node/nextjs'
3+
import { verifySession } from 'supertokens-node/recipe/session'
4+
5+
export default async function user(req, res) {
6+
if (req.method !== 'GET') {
7+
return res.end()
8+
}
9+
10+
await superTokensNextWrapper(
11+
async (next) => {
12+
return await verifySession()(req, res, next)
13+
},
14+
req,
15+
res
16+
)
17+
18+
return res.json({
19+
note:
20+
'Fetch any data from your application for authenticated user after using verifySession middleware',
21+
userId: req.session.userId,
22+
sessionHandle: req.session.sessionHandle,
23+
userDataInJWT: req.session.userDataInJWT,
24+
})
25+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import Head from 'next/head'
2+
import React, { useEffect } from 'react'
3+
import styles from '../../styles/Home.module.css'
4+
import dynamic from 'next/dynamic'
5+
import SuperTokens from 'supertokens-auth-react'
6+
7+
const SuperTokensComponentNoSSR = dynamic(
8+
() =>
9+
Promise.resolve().then(() => {
10+
return () => SuperTokens.getRoutingComponent() || null
11+
}),
12+
{
13+
ssr: false,
14+
}
15+
)
16+
17+
export default function Auth() {
18+
useEffect(() => {
19+
if (SuperTokens.canHandleRoute() === false) {
20+
window.location.href = '/'
21+
}
22+
}, [])
23+
24+
return (
25+
<div className={styles.container}>
26+
<Head>
27+
<title>SuperTokens 💫</title>
28+
<link rel="icon" href="/favicon.ico" />
29+
</Head>
30+
31+
<main className={styles.main}>
32+
<SuperTokensComponentNoSSR />
33+
</main>
34+
</div>
35+
)
36+
}
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
import React from 'react'
2+
import Head from 'next/head'
3+
import styles from '../styles/Home.module.css'
4+
import EmailPassword from 'supertokens-auth-react/recipe/emailpassword'
5+
import dynamic from 'next/dynamic'
6+
7+
const EmailPasswordAuthNoSSR = dynamic(
8+
() => Promise.resolve().then(() => EmailPassword.EmailPasswordAuth),
9+
{
10+
ssr: false,
11+
}
12+
)
13+
14+
export default function Home() {
15+
async function logoutClicked() {
16+
await EmailPassword.signOut()
17+
window.location.href = '/auth'
18+
}
19+
20+
async function fetchUserData() {
21+
const res = await fetch('/api/user')
22+
const json = await res.json()
23+
alert(JSON.stringify(json))
24+
}
25+
26+
return (
27+
<div className={styles.container}>
28+
<Head>
29+
<title>SuperTokens 💫</title>
30+
<link rel="icon" href="/favicon.ico" />
31+
</Head>
32+
33+
<main className={styles.main}>
34+
<h1 className={styles.title}>
35+
Welcome to <a href="https://nextjs.org">Next.js!</a>
36+
</h1>
37+
<EmailPasswordAuthNoSSR>
38+
<p className={styles.description}>
39+
You are authenticated with SuperTokens!
40+
</p>
41+
42+
<div
43+
style={{
44+
display: 'flex',
45+
height: '70px',
46+
alignItems: 'center',
47+
justifyContent: 'flex-end',
48+
paddingLeft: '75px',
49+
paddingRight: '75px',
50+
}}
51+
>
52+
<div
53+
onClick={logoutClicked}
54+
style={{
55+
display: 'flex',
56+
width: '116px',
57+
height: '42px',
58+
backgroundColor: '#000000',
59+
borderRadius: '10px',
60+
cursor: 'pointer',
61+
alignItems: 'center',
62+
justifyContent: 'center',
63+
color: '#ffffff',
64+
fontWeight: 'bold',
65+
}}
66+
>
67+
SIGN OUT
68+
</div>
69+
</div>
70+
<div
71+
style={{
72+
display: 'flex',
73+
height: '70px',
74+
alignItems: 'center',
75+
justifyContent: 'flex-end',
76+
paddingLeft: '75px',
77+
paddingRight: '75px',
78+
}}
79+
>
80+
<div
81+
onClick={fetchUserData}
82+
style={{
83+
display: 'flex',
84+
width: '150px',
85+
height: '42px',
86+
backgroundColor: 'rgb(247 54 54)',
87+
borderRadius: '10px',
88+
cursor: 'pointer',
89+
alignItems: 'center',
90+
justifyContent: 'center',
91+
color: '#ffffff',
92+
fontWeight: 'bold',
93+
}}
94+
>
95+
FETCH USER API
96+
</div>
97+
</div>
98+
</EmailPasswordAuthNoSSR>
99+
100+
<div className={styles.grid}>
101+
<a href="https://nextjs.org/docs" className={styles.card}>
102+
<h3>Documentation &rarr;</h3>
103+
<p>Find in-depth information about Next.js features and API.</p>
104+
</a>
105+
106+
<a href="https://nextjs.org/learn" className={styles.card}>
107+
<h3>Learn &rarr;</h3>
108+
<p>Learn about Next.js in an interactive course with quizzes!</p>
109+
</a>
110+
111+
<a
112+
href="https://github.com/vercel/next.js/tree/master/examples"
113+
className={styles.card}
114+
>
115+
<h3>Examples &rarr;</h3>
116+
<p>Discover and deploy boilerplate example Next.js projects.</p>
117+
</a>
118+
119+
<a
120+
href="https://vercel.com/import?filter=next.js&utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
121+
className={styles.card}
122+
>
123+
<h3>Deploy &rarr;</h3>
124+
<p>
125+
Instantly deploy your Next.js site to a public URL with Vercel.
126+
</p>
127+
</a>
128+
</div>
129+
</main>
130+
131+
<footer className={styles.footer}>
132+
<a
133+
href="https://vercel.com?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
134+
target="_blank"
135+
rel="noopener noreferrer"
136+
>
137+
Powered by{' '}
138+
<img src="/vercel.svg" alt="Vercel Logo" className={styles.logo} />
139+
</a>
140+
</footer>
141+
</div>
142+
)
143+
}
9.44 KB
Binary file not shown.

0 commit comments

Comments
 (0)