mirror of
https://github.com/supabase/supabase.git
synced 2026-06-06 05:17:15 +08:00
Update examples with latest auth helpers
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -5,23 +5,23 @@
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
"start": "next start"
|
||||
"start": "next start",
|
||||
"lint": "next lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"@supabase/auth-helpers-nextjs": "^0.5.4",
|
||||
"@supabase/auth-helpers-react": "^0.3.1",
|
||||
"@supabase/auth-ui-react": "^0.2.6",
|
||||
"@supabase/supabase-js": "^2.5.0",
|
||||
"next": "12.3.1",
|
||||
"@supabase/auth-helpers-nextjs": "^0.7.0-next.6",
|
||||
"@supabase/auth-helpers-react": "^0.4.0-next.0",
|
||||
"@supabase/auth-ui-react": "^0.4.2",
|
||||
"@supabase/auth-ui-shared": "^0.1.6",
|
||||
"@supabase/supabase-js": "^2.21.0",
|
||||
"@types/node": "20.1.4",
|
||||
"@types/react": "18.2.6",
|
||||
"@types/react-dom": "18.2.4",
|
||||
"eslint": "8.40.0",
|
||||
"eslint-config-next": "13.4.2",
|
||||
"next": "13.4.2",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "18.8.5",
|
||||
"@types/react": "18.0.21",
|
||||
"@types/react-dom": "18.0.6",
|
||||
"eslint": "8.25.0",
|
||||
"eslint-config-next": "12.3.1",
|
||||
"typescript": "4.8.4"
|
||||
"react-dom": "18.2.0",
|
||||
"typescript": "5.0.4"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import '../styles/globals.css'
|
||||
import { useState } from 'react'
|
||||
import type { AppProps } from 'next/app'
|
||||
import { createBrowserSupabaseClient } from '@supabase/auth-helpers-nextjs'
|
||||
import { createPagesBrowserClient } from '@supabase/auth-helpers-nextjs'
|
||||
import { SessionContextProvider, Session } from '@supabase/auth-helpers-react'
|
||||
|
||||
function MyApp({
|
||||
@@ -10,7 +10,7 @@ function MyApp({
|
||||
}: AppProps<{
|
||||
initialSession: Session
|
||||
}>) {
|
||||
const [supabaseClient] = useState(() => createBrowserSupabaseClient())
|
||||
const [supabaseClient] = useState(() => createPagesBrowserClient())
|
||||
|
||||
return (
|
||||
<SessionContextProvider
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import { NextApiRequest, NextApiResponse } from 'next'
|
||||
import { createPagesServerClient } from '@supabase/auth-helpers-nextjs'
|
||||
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
// Create authenticated Supabase Client
|
||||
const supabase = createPagesServerClient({ req, res })
|
||||
|
||||
const code = req.query.code
|
||||
|
||||
if (typeof code === 'string') {
|
||||
await supabase.auth.exchangeCodeForSession(code)
|
||||
}
|
||||
|
||||
res.redirect('/')
|
||||
}
|
||||
@@ -1,37 +1,55 @@
|
||||
import type { NextPage } from 'next'
|
||||
import { Auth, ThemeSupa } from '@supabase/auth-ui-react'
|
||||
import { Auth } from '@supabase/auth-ui-react'
|
||||
import { ThemeSupa } from '@supabase/auth-ui-shared'
|
||||
import { useSession, useSupabaseClient } from '@supabase/auth-helpers-react'
|
||||
import Account from '../components/Account'
|
||||
import Footer from '../components/Footer'
|
||||
import Head from 'next/head'
|
||||
|
||||
const Home: NextPage = () => {
|
||||
const session = useSession()
|
||||
const supabase = useSupabaseClient()
|
||||
|
||||
return (
|
||||
<div className="container" style={{ padding: '50px 0 100px 0' }}>
|
||||
{!session ? (
|
||||
<div className="row">
|
||||
<div className="col-6">
|
||||
<h1 className="header">Supabase Auth + Storage</h1>
|
||||
<p className="">
|
||||
Experience our Auth and Storage through a simple profile management example. Create a
|
||||
user profile and upload an avatar image. Fast, simple, secure.
|
||||
</p>
|
||||
<>
|
||||
<Head>
|
||||
<title>User Management</title>
|
||||
<meta name="description" content="Generated by create next app" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
</Head>
|
||||
<div className="container" style={{ padding: '50px 0 100px 0' }}>
|
||||
{!session ? (
|
||||
<div className="row">
|
||||
<div className="col-6">
|
||||
<h1 className="header">Supabase Auth + Storage</h1>
|
||||
<p className="">
|
||||
Experience our Auth and Storage through a simple profile management example. Create
|
||||
a user profile and upload an avatar image. Fast, simple, secure.
|
||||
</p>
|
||||
</div>
|
||||
<div className="col-6 auth-widget">
|
||||
<Auth
|
||||
supabaseClient={supabase}
|
||||
view="magic_link"
|
||||
redirectTo="http://localhost:3000/api/auth/callback"
|
||||
appearance={{ theme: ThemeSupa }}
|
||||
theme="dark"
|
||||
showLinks={false}
|
||||
providers={[]}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-6 auth-widget">
|
||||
<Auth supabaseClient={supabase} appearance={{ theme: ThemeSupa }} theme="dark" />
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<h3>Account</h3>
|
||||
<Account session={session} />
|
||||
</>
|
||||
)}
|
||||
) : (
|
||||
<>
|
||||
<h3>Account</h3>
|
||||
<Account session={session} />
|
||||
</>
|
||||
)}
|
||||
|
||||
<Footer />
|
||||
</div>
|
||||
<Footer />
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
import { createRouteHandlerSupabaseClient } from "@supabase/auth-helpers-nextjs";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { createRouteHandlerClient } from '@supabase/auth-helpers-nextjs'
|
||||
import { cookies } from 'next/headers'
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
|
||||
export async function GET(req: NextRequest) {
|
||||
const res = NextResponse.redirect(new URL("/account", req.url));
|
||||
const supabase = createRouteHandlerSupabaseClient({ req, res });
|
||||
const { searchParams } = new URL(req.url);
|
||||
const code = searchParams.get("code");
|
||||
const res = NextResponse.redirect(new URL('/account', req.url))
|
||||
const supabase = createRouteHandlerClient({ cookies })
|
||||
const { searchParams } = new URL(req.url)
|
||||
const code = searchParams.get('code')
|
||||
|
||||
if (code) {
|
||||
await supabase.auth.exchangeCodeForSession(code);
|
||||
await supabase.auth.exchangeCodeForSession(code)
|
||||
}
|
||||
|
||||
return res;
|
||||
return res
|
||||
}
|
||||
|
||||
@@ -1,20 +1,21 @@
|
||||
import { createRouteHandlerSupabaseClient } from "@supabase/auth-helpers-nextjs";
|
||||
import { type NextRequest, NextResponse } from "next/server";
|
||||
import { createRouteHandlerClient } from '@supabase/auth-helpers-nextjs'
|
||||
import { cookies } from 'next/headers'
|
||||
import { type NextRequest, NextResponse } from 'next/server'
|
||||
|
||||
export async function POST(req: NextRequest) {
|
||||
const res = NextResponse.redirect(new URL("/", req.url), {
|
||||
const res = NextResponse.redirect(new URL('/', req.url), {
|
||||
status: 302,
|
||||
});
|
||||
const supabase = createRouteHandlerSupabaseClient({ req, res });
|
||||
})
|
||||
const supabase = createRouteHandlerClient({ cookies })
|
||||
|
||||
// Check if we have a session
|
||||
const {
|
||||
data: { session },
|
||||
} = await supabase.auth.getSession();
|
||||
} = await supabase.auth.getSession()
|
||||
|
||||
if (session) {
|
||||
await supabase.auth.signOut();
|
||||
await supabase.auth.signOut()
|
||||
}
|
||||
|
||||
return res;
|
||||
return res
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
"use client";
|
||||
import { Auth } from "@supabase/auth-ui-react";
|
||||
import { ThemeSupa } from "@supabase/auth-ui-shared";
|
||||
import { useSupabase } from "./supabase-provider";
|
||||
'use client'
|
||||
import { Auth } from '@supabase/auth-ui-react'
|
||||
import { ThemeSupa } from '@supabase/auth-ui-shared'
|
||||
import { useSupabase } from './supabase-provider'
|
||||
|
||||
export default function AuthForm() {
|
||||
const { supabase } = useSupabase();
|
||||
const { supabase } = useSupabase()
|
||||
|
||||
return (
|
||||
<Auth
|
||||
@@ -16,5 +16,5 @@ export default function AuthForm() {
|
||||
providers={[]}
|
||||
redirectTo="http://localhost:3000/auth/callback"
|
||||
/>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,35 +1,31 @@
|
||||
import "./globals.css";
|
||||
import { createServerComponentSupabaseClient } from "@supabase/auth-helpers-nextjs";
|
||||
import SupabaseProvider from "./supabase-provider";
|
||||
import { cookies } from "next/headers";
|
||||
import './globals.css'
|
||||
import { createServerComponentClient } from '@supabase/auth-helpers-nextjs'
|
||||
import SupabaseProvider from './supabase-provider'
|
||||
import { cookies } from 'next/headers'
|
||||
|
||||
export const metadata = {
|
||||
title: "Create Next App",
|
||||
description: "Generated by create next app",
|
||||
};
|
||||
title: 'Create Next App',
|
||||
description: 'Generated by create next app',
|
||||
}
|
||||
|
||||
export default async function RootLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
const supabase = createServerComponentSupabaseClient({
|
||||
export default async function RootLayout({ children }: { children: React.ReactNode }) {
|
||||
const supabase = createServerComponentClient({
|
||||
cookies,
|
||||
});
|
||||
})
|
||||
|
||||
const {
|
||||
data: { session },
|
||||
} = await supabase.auth.getSession();
|
||||
} = await supabase.auth.getSession()
|
||||
|
||||
return (
|
||||
<html lang="en">
|
||||
<body>
|
||||
<SupabaseProvider session={session}>
|
||||
<div className="container" style={{ padding: "50px 0 100px 0" }}>
|
||||
<div className="container" style={{ padding: '50px 0 100px 0' }}>
|
||||
{children}
|
||||
</div>
|
||||
</SupabaseProvider>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,60 +1,56 @@
|
||||
"use client";
|
||||
'use client'
|
||||
|
||||
import { createContext, useContext, useEffect, useState } from "react";
|
||||
import {
|
||||
Session,
|
||||
SupabaseClient,
|
||||
createBrowserSupabaseClient,
|
||||
} from "@supabase/auth-helpers-nextjs";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { Database } from "./database.types";
|
||||
import { createContext, useContext, useEffect, useState } from 'react'
|
||||
import { Session, SupabaseClient, createClientComponentClient } from '@supabase/auth-helpers-nextjs'
|
||||
import { useRouter } from 'next/navigation'
|
||||
import { Database } from './database.types'
|
||||
|
||||
type MaybeSession = Session | null;
|
||||
type MaybeSession = Session | null
|
||||
|
||||
type SupabaseContext = {
|
||||
supabase: SupabaseClient;
|
||||
session: MaybeSession;
|
||||
};
|
||||
supabase: SupabaseClient
|
||||
session: MaybeSession
|
||||
}
|
||||
|
||||
const Context = createContext<SupabaseContext | undefined>(undefined);
|
||||
const Context = createContext<SupabaseContext | undefined>(undefined)
|
||||
|
||||
export default function SupabaseProvider({
|
||||
children,
|
||||
session,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
session: MaybeSession;
|
||||
children: React.ReactNode
|
||||
session: MaybeSession
|
||||
}) {
|
||||
const [supabase] = useState(() => createBrowserSupabaseClient<Database>());
|
||||
const router = useRouter();
|
||||
const [supabase] = useState(() => createClientComponentClient<Database>())
|
||||
const router = useRouter()
|
||||
|
||||
useEffect(() => {
|
||||
const {
|
||||
data: { subscription },
|
||||
} = supabase.auth.onAuthStateChange((_, _session) => {
|
||||
if (_session?.access_token !== session?.access_token) {
|
||||
router.refresh();
|
||||
router.refresh()
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
return () => {
|
||||
subscription.unsubscribe();
|
||||
};
|
||||
}, [router, supabase, session]);
|
||||
subscription.unsubscribe()
|
||||
}
|
||||
}, [router, supabase, session])
|
||||
|
||||
return (
|
||||
<Context.Provider value={{ supabase, session }}>
|
||||
<>{children}</>
|
||||
</Context.Provider>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
export const useSupabase = () => {
|
||||
let context = useContext(Context);
|
||||
let context = useContext(Context)
|
||||
|
||||
if (context === undefined) {
|
||||
throw new Error("useSupabase must be used inside SupabaseProvider");
|
||||
throw new Error('useSupabase must be used inside SupabaseProvider')
|
||||
}
|
||||
|
||||
return context;
|
||||
};
|
||||
return context
|
||||
}
|
||||
|
||||
@@ -1,27 +1,29 @@
|
||||
import { createMiddlewareSupabaseClient } from "@supabase/auth-helpers-nextjs";
|
||||
import { NextResponse } from "next/server";
|
||||
import { createMiddlewareClient } from '@supabase/auth-helpers-nextjs'
|
||||
import { NextResponse } from 'next/server'
|
||||
|
||||
import type { NextRequest } from "next/server";
|
||||
import type { NextRequest } from 'next/server'
|
||||
|
||||
export async function middleware(req: NextRequest) {
|
||||
const res = NextResponse.next();
|
||||
const supabase = createMiddlewareSupabaseClient({ req, res });
|
||||
const res = NextResponse.next()
|
||||
const supabase = createMiddlewareClient({ req, res })
|
||||
|
||||
const {
|
||||
data: { user },
|
||||
} = await supabase.auth.getUser();
|
||||
} = await supabase.auth.getUser()
|
||||
|
||||
if (user && req.nextUrl.pathname === "/") {
|
||||
return NextResponse.redirect(new URL("/account", req.url));
|
||||
// if user is signed in and the current path is / redirect the user to /account
|
||||
if (user && req.nextUrl.pathname === '/') {
|
||||
return NextResponse.redirect(new URL('/account', req.url))
|
||||
}
|
||||
|
||||
if (!user && req.nextUrl.pathname !== "/") {
|
||||
return NextResponse.redirect(new URL("/", req.url));
|
||||
// if user is not signed in and the current path is not / redirect the user to /
|
||||
if (!user && req.nextUrl.pathname !== '/') {
|
||||
return NextResponse.redirect(new URL('/', req.url))
|
||||
}
|
||||
|
||||
return res;
|
||||
return res
|
||||
}
|
||||
|
||||
export const config = {
|
||||
matcher: ["/", "/account"],
|
||||
};
|
||||
matcher: ['/', '/account'],
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"name": "nextjs-user-management",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@supabase/auth-helpers-nextjs": "^0.7.0-next.5",
|
||||
"@supabase/auth-helpers-nextjs": "^0.7.0-next.6",
|
||||
"@supabase/auth-ui-react": "^0.4.2",
|
||||
"@supabase/auth-ui-shared": "^0.1.6",
|
||||
"@types/node": "20.1.4",
|
||||
@@ -326,9 +326,9 @@
|
||||
"integrity": "sha512-Gfkvwk9o9kE9r9XNBmJRfV8zONvXThnm1tcuojL04Uy5uRyqg93DC83lDebl0rocZCfKSjUv+fWYtMQmEDJldg=="
|
||||
},
|
||||
"node_modules/@supabase/auth-helpers-nextjs": {
|
||||
"version": "0.7.0-next.5",
|
||||
"resolved": "https://registry.npmjs.org/@supabase/auth-helpers-nextjs/-/auth-helpers-nextjs-0.7.0-next.5.tgz",
|
||||
"integrity": "sha512-fmCnjaVzZ09ssTDV4g4CjS+ykT2QIRpw2r6cCMXC/6Qa3NiXbgYI1LpLhSOcrDXb7eVZQkTTl0LAAe5Dphb/5A==",
|
||||
"version": "0.7.0-next.6",
|
||||
"resolved": "https://registry.npmjs.org/@supabase/auth-helpers-nextjs/-/auth-helpers-nextjs-0.7.0-next.6.tgz",
|
||||
"integrity": "sha512-2mR4Y/1znDXVqP5Q1DzSvTkdDBke+BABxoW8+1YhVIDrUU//mQsGIjmnusfiUgQPhSHToCJMbLWKuCwPx9SyFQ==",
|
||||
"dependencies": {
|
||||
"@supabase/auth-helpers-shared": "0.4.0-next.3",
|
||||
"set-cookie-parser": "^2.6.0"
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"lint": "next lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"@supabase/auth-helpers-nextjs": "^0.7.0-next.5",
|
||||
"@supabase/auth-helpers-nextjs": "^0.7.0-next.6",
|
||||
"@supabase/auth-ui-react": "^0.4.2",
|
||||
"@supabase/auth-ui-shared": "^0.1.6",
|
||||
"@types/node": "20.1.4",
|
||||
|
||||
Reference in New Issue
Block a user