Merge pull request #5464 from supabase/example/update-nextjs-with-auth

feat: update nextjs auth example
This commit is contained in:
Thor 雷神 Schaeff authored and GitHub committed 2022-02-18 16:39:21 +08:00
commit b5fdbb7d02
10 files changed
+2868 -2585

No files matched your search

File diff suppressed because it is too large. Load diff
@@ -7,9 +7,8 @@
"start": "next start"
},
"dependencies": {
"@supabase/supabase-js": "^1.11.9",
"@supabase/ui": "^0.24.2",
"next": "11.1.1",
"@supabase/supabase-auth-helpers": "^1.0.6",
"next": "^11.1.4",
"react": "17.0.2",
"react-dom": "17.0.2",
"swr": "^0.5.5"
@@ -1,13 +1,13 @@
import { Auth } from '@supabase/ui'
import { supabase } from '../utils/initSupabase'
import { UserProvider } from '@supabase/supabase-auth-helpers/react'
import { supabaseClient } from '@supabase/supabase-auth-helpers/nextjs'
import './../style.css'
export default function MyApp({ Component, pageProps }) {
return (
<main className={'dark'}>
<Auth.UserContextProvider supabaseClient={supabase}>
<UserProvider supabaseClient={supabaseClient}>
<Component {...pageProps} />
</Auth.UserContextProvider>
</UserProvider>
</main>
)
}
@@ -1,8 +0,0 @@
/**
* NOTE: this file is only needed if you're doing SSR (getServerSideProps)!
*/
import { supabase } from '../../utils/initSupabase'
export default function handler(req, res) {
supabase.auth.api.setAuthCookie(req, res)
}
@@ -0,0 +1,3 @@
import { handleAuth } from '@supabase/supabase-auth-helpers/nextjs'
export default handleAuth()
@@ -1,13 +0,0 @@
import { supabase } from '../../utils/initSupabase'
// Example of how to verify and get user data server-side.
const getUser = async (req, res) => {
const token = req.headers.token
const { data: user, error } = await supabase.auth.api.getUser(token)
if (error) return res.status(401).json({ error: error.message })
return res.status(200).json(user)
}
export default getUser
@@ -1,106 +1,43 @@
import Link from 'next/link'
import useSWR from 'swr'
import { Auth, Card, Typography, Space, Button, Icon } from '@supabase/ui'
import { supabase } from '../utils/initSupabase'
import { useUser, Auth } from '@supabase/supabase-auth-helpers/react'
import { supabaseClient } from '@supabase/supabase-auth-helpers/nextjs'
import { useEffect, useState } from 'react'
const fetcher = (url, token) =>
fetch(url, {
method: 'GET',
headers: new Headers({ 'Content-Type': 'application/json', token }),
credentials: 'same-origin',
}).then((res) => res.json())
const Index = () => {
const { user, session } = Auth.useUser()
const { data, error } = useSWR(session ? ['/api/getUser', session.access_token] : null, fetcher)
const [authView, setAuthView] = useState('sign_in')
const LoginPage = () => {
const { user, error } = useUser()
const [data, setData] = useState({})
useEffect(() => {
const { data: authListener } = supabase.auth.onAuthStateChange((event, session) => {
if (event === 'PASSWORD_RECOVERY') setAuthView('forgotten_password')
if (event === 'USER_UPDATED') setTimeout(() => setAuthView('sign_in'), 1000)
// Send session to /api/auth route to set the auth cookie.
// NOTE: this is only needed if you're doing SSR (getServerSideProps)!
fetch('/api/auth', {
method: 'POST',
headers: new Headers({ 'Content-Type': 'application/json' }),
credentials: 'same-origin',
body: JSON.stringify({ event, session }),
}).then((res) => res.json())
})
return () => {
authListener.unsubscribe()
async function loadData() {
const { data } = await supabaseClient.from('test').select('*')
setData(data)
}
}, [])
const View = () => {
if (!user)
return (
<Space direction="vertical" size={8}>
<div>
<img src="https://app.supabase.io/img/supabase-dark.svg" width="96" />
<Typography.Title level={3}>Welcome to Supabase Auth</Typography.Title>
</div>
<Auth
supabaseClient={supabase}
providers={['google', 'github']}
view={authView}
socialLayout="horizontal"
socialButtonSize="xlarge"
/>
</Space>
)
// Only run query once user is logged in.
if (user) loadData()
}, [user])
if (!user)
return (
<Space direction="vertical" size={6}>
{authView === 'forgotten_password' && <Auth.UpdatePassword supabaseClient={supabase} />}
{user && (
<>
<Typography.Text>You're signed in</Typography.Text>
<Typography.Text strong>Email: {user.email}</Typography.Text>
<Button
icon={<Icon type="LogOut" />}
type="outline"
onClick={() => supabase.auth.signOut()}
>
Log out
</Button>
{error && <Typography.Text type="danger">Failed to fetch user!</Typography.Text>}
{data && !error ? (
<>
<Typography.Text type="success">
User data retrieved server-side (in API route):
</Typography.Text>
<Typography.Text>
<pre>{JSON.stringify(data, null, 2)}</pre>
</Typography.Text>
</>
) : (
<div>Loading...</div>
)}
<Typography.Text>
<Link href="/profile">
<a>SSR example with getServerSideProps</a>
</Link>
</Typography.Text>
</>
)}
</Space>
<>
{error && <p>{error.message}</p>}
<Auth
// view="update_password"
supabaseClient={supabaseClient}
providers={['google', 'github']}
socialLayout="horizontal"
socialButtonSize="xlarge"
/>
</>
)
}
return (
<div style={{ maxWidth: '420px', margin: '96px auto' }}>
<Card>
<View />
</Card>
</div>
<>
<button onClick={() => supabaseClient.auth.signOut()}>Sign out</button>
<p>user:</p>
<pre>{JSON.stringify(user, null, 2)}</pre>
<p>client-side data fetching with RLS</p>
<pre>{JSON.stringify(data, null, 2)}</pre>
</>
)
}
export default Index
export default LoginPage
@@ -1,41 +1,13 @@
import Link from 'next/link'
import { Card, Typography, Space } from '@supabase/ui'
import { supabase } from '../utils/initSupabase'
// pages/profile.js
import { withAuthRequired } from '@supabase/supabase-auth-helpers/nextjs'
export default function Profile({ user }) {
return (
<div style={{ maxWidth: '420px', margin: '96px auto' }}>
<Card>
<Space direction="vertical" size={6}>
<Typography.Text>You're signed in</Typography.Text>
<Typography.Text strong>Email: {user.email}</Typography.Text>
<Typography.Text type="success">
User data retrieved server-side (from Cookie in getServerSideProps):
</Typography.Text>
<Typography.Text>
<pre>{JSON.stringify(user, null, 2)}</pre>
</Typography.Text>
<Typography.Text>
<Link href="/">
<a>Static example with useSWR</a>
</Link>
</Typography.Text>
</Space>
</Card>
</div>
<>
<div>Hello {user.email}</div>
<pre>{JSON.stringify(user, null, 2)}</pre>
</>
)
}
export async function getServerSideProps({ req }) {
const { user } = await supabase.auth.api.getUserByCookie(req)
if (!user) {
// If no user, redirect to index.
return { props: {}, redirect: { destination: '/', permanent: false } }
}
// If there is a user, return it.
return { props: { user } }
}
export const getServerSideProps = withAuthRequired()
@@ -1,6 +0,0 @@
import { createClient } from '@supabase/supabase-js'
export const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY
)
File diff suppressed because it is too large. Load diff