mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
docs: Update nextjs user management guide to use getClaims (#44124)
This commit is contained in:
1 parent
fa4a668eeb
commit
8e33378315
7 files changed
+1296
-1401
No files matched your search
@@ -1,10 +1,11 @@
|
||||
'use client'
|
||||
import { useCallback, useEffect, useState } from 'react'
|
||||
import { createClient } from '@/lib/supabase/client'
|
||||
import { type User } from '@supabase/supabase-js'
|
||||
import Avatar from './avatar'
|
||||
|
||||
export default function AccountForm({ user }: { user: User | null }) {
|
||||
type Claims = { sub: string; email?: string; [key: string]: unknown }
|
||||
|
||||
export default function AccountForm({ claims }: { claims: Claims | null }) {
|
||||
const supabase = createClient()
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [fullname, setFullname] = useState<string | null>(null)
|
||||
@@ -14,12 +15,17 @@ export default function AccountForm({ user }: { user: User | null }) {
|
||||
|
||||
const getProfile = useCallback(async () => {
|
||||
try {
|
||||
if (!claims?.sub) {
|
||||
setLoading(false)
|
||||
return
|
||||
}
|
||||
|
||||
setLoading(true)
|
||||
|
||||
const { data, error, status } = await supabase
|
||||
.from('profiles')
|
||||
.select(`full_name, username, website, avatar_url`)
|
||||
.eq('id', user?.id)
|
||||
.eq('id', claims.sub)
|
||||
.single()
|
||||
|
||||
if (error && status !== 406) {
|
||||
@@ -38,11 +44,11 @@ export default function AccountForm({ user }: { user: User | null }) {
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}, [user, supabase])
|
||||
}, [claims, supabase])
|
||||
|
||||
useEffect(() => {
|
||||
getProfile()
|
||||
}, [user, getProfile])
|
||||
}, [claims, getProfile])
|
||||
|
||||
async function updateProfile({
|
||||
username,
|
||||
@@ -55,10 +61,15 @@ export default function AccountForm({ user }: { user: User | null }) {
|
||||
avatar_url: string | null
|
||||
}) {
|
||||
try {
|
||||
if (!claims?.sub) {
|
||||
alert('You must be logged in to update your profile')
|
||||
return
|
||||
}
|
||||
|
||||
setLoading(true)
|
||||
|
||||
const { error } = await supabase.from('profiles').upsert({
|
||||
id: user?.id as string,
|
||||
id: claims.sub,
|
||||
full_name: fullname,
|
||||
username,
|
||||
website,
|
||||
@@ -77,7 +88,7 @@ export default function AccountForm({ user }: { user: User | null }) {
|
||||
return (
|
||||
<div className="form-widget">
|
||||
<Avatar
|
||||
uid={user?.id ?? null}
|
||||
uid={claims?.sub ?? null}
|
||||
url={avatar_url}
|
||||
size={150}
|
||||
onUpload={(url) => {
|
||||
@@ -87,7 +98,7 @@ export default function AccountForm({ user }: { user: User | null }) {
|
||||
/>
|
||||
<div>
|
||||
<label htmlFor="email">Email</label>
|
||||
<input id="email" type="text" value={user?.email} disabled />
|
||||
<input id="email" type="text" value={claims?.email ?? ''} disabled />
|
||||
</div>
|
||||
<div>
|
||||
<label htmlFor="fullName">Full Name</label>
|
||||
@@ -121,7 +132,7 @@ export default function AccountForm({ user }: { user: User | null }) {
|
||||
<button
|
||||
className="button primary block"
|
||||
onClick={() => updateProfile({ fullname, username, website, avatar_url })}
|
||||
disabled={loading}
|
||||
disabled={loading || !claims?.sub}
|
||||
>
|
||||
{loading ? 'Loading ...' : 'Update'}
|
||||
</button>
|
||||
|
||||
@@ -4,9 +4,7 @@ import { createClient } from '@/lib/supabase/server'
|
||||
export default async function Account() {
|
||||
const supabase = await createClient()
|
||||
|
||||
const {
|
||||
data: { user },
|
||||
} = await supabase.auth.getUser()
|
||||
const { data: claimsData } = await supabase.auth.getClaims()
|
||||
|
||||
return <AccountForm user={user} />
|
||||
return <AccountForm claims={claimsData?.claims ?? null} />
|
||||
}
|
||||
@@ -6,11 +6,9 @@ export async function POST(req: NextRequest) {
|
||||
const supabase = await createClient()
|
||||
|
||||
// Check if a user's logged in
|
||||
const {
|
||||
data: { user },
|
||||
} = await supabase.auth.getUser()
|
||||
const { data: claimsData } = await supabase.auth.getClaims()
|
||||
|
||||
if (user) {
|
||||
if (claimsData?.claims) {
|
||||
await supabase.auth.signOut()
|
||||
}
|
||||
|
||||
|
||||
@@ -27,8 +27,13 @@ export async function updateSession(request: NextRequest) {
|
||||
}
|
||||
)
|
||||
|
||||
// refreshing the auth token
|
||||
await supabase.auth.getUser()
|
||||
// Do not run code between createServerClient and
|
||||
// supabase.auth.getClaims(). A simple mistake could make it very hard to debug
|
||||
// issues with users being randomly logged out.
|
||||
|
||||
// IMPORTANT: If you remove getClaims() and you use server-side rendering
|
||||
// with the Supabase client, your users may be randomly logged out.
|
||||
await supabase.auth.getClaims()
|
||||
|
||||
return supabaseResponse
|
||||
}
|
||||
+1241
-1360
File diff suppressed because it is too large.
Load diff
@@ -9,20 +9,20 @@
|
||||
"lint": "next lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"@supabase/ssr": "^0.6.1",
|
||||
"@supabase/supabase-js": "^2.53.0",
|
||||
"next": "latest",
|
||||
"react": "19.1.1",
|
||||
"react-dom": "19.1.1"
|
||||
"@supabase/ssr": "^0.9.0",
|
||||
"@supabase/supabase-js": "^2.100.0",
|
||||
"next": "^16.2.1",
|
||||
"react": "^19.2.4",
|
||||
"react-dom": "^19.2.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/postcss": "^4.1.11",
|
||||
"@types/node": "^24.2.0",
|
||||
"@types/react": "^19.1.9",
|
||||
"@types/react-dom": "^19.1.7",
|
||||
"eslint": "^9.32.0",
|
||||
"eslint-config-next": "15.4.5",
|
||||
"tailwindcss": "^4.1.11",
|
||||
"typescript": "^5"
|
||||
"@tailwindcss/postcss": "^4.2.2",
|
||||
"@types/node": "^25.5.0",
|
||||
"@types/react": "^19.2.14",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"eslint": "^10.1.0",
|
||||
"eslint-config-next": "16.2.1",
|
||||
"tailwindcss": "^4.2.2",
|
||||
"typescript": "^6.0.2"
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user