-
Notifications
You must be signed in to change notification settings - Fork 135
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(session): add support for retrieving user session (#338)
- Loading branch information
1 parent
ee5670b
commit 07eb081
Showing
5 changed files
with
126 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
--- | ||
title: useSupabaseSession | ||
description: Auto import and use your Supabase user's session with the useSupabaseSession composable | ||
--- | ||
|
||
Once logged in, you can [auto-import](https://nuxt.com/docs/guide/directory-structure/composables) your user's session everywhere inside your vue files. | ||
|
||
```vue | ||
<script setup> | ||
const session = useSupabaseSession() | ||
</script> | ||
``` | ||
|
||
::callout{icon="i-heroicons-light-bulb"} | ||
If you just need the User's information you can use [useSupabaseUser](/usage/composables/usesupabaseuser) which returns just the User information of the session. | ||
:: | ||
|
||
## Auth middleware | ||
|
||
::callout{icon="i-heroicons-light-bulb"} | ||
By default, the module is implementing a redirect middleware. All pages of your application are automatically redirected to the [login](/get-started#redirectoptions) page. However, you can allow redirection to "public" pages by setting the [exclude](/get-started#redirectoptions) redirect option. Alternatively, you can enable the redirect only for certain routes using the [include](/get-started#redirectoptions) redirect option. | ||
:: | ||
|
||
If the [redirect](/get-started#redirect) option is disabled, you can protect your authenticated routes by creating a custom middleware in your project, here is an example: | ||
|
||
```ts [middleware/auth.ts] | ||
export default defineNuxtRouteMiddleware((to, _from) => { | ||
const session = useSupabaseSession() | ||
|
||
if (!session.value) { | ||
return navigateTo('/login') | ||
} | ||
}) | ||
``` | ||
|
||
Then you can reference your middleware in your page with: | ||
|
||
```ts [pages/dashboard.vue] | ||
definePageMeta({ | ||
middleware: 'auth' | ||
}) | ||
``` | ||
|
||
Learn more about [Nuxt middleware](https://nuxt.com/docs/guide/directory-structure/middleware) and [definePageMeta](https://nuxt.com/docs/guide/directory-structure/pages#page-metadata). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
--- | ||
title: serverSupabaseSession | ||
description: Get your Supabase user's session from serverside with the serverSupabaseUser service | ||
--- | ||
|
||
::callout{color="amber" icon="i-heroicons-exclamation-triangle-20-solid"} | ||
This section assumes you're familiar with [Nitro](https://v3.nuxtjs.org/guide/concepts/server-engine), the server engine powered by Nuxt. | ||
:: | ||
|
||
This function is similar to the [useSupabaseSession](/usage/composables/usesupabasesession) composable but is used in [server routes](https://nuxt.com/docs/guide/directory-structure/server#server-routes). | ||
|
||
Define your server route and import the `serverSupabaseSession` from `#supabase/server`. | ||
|
||
```ts [server/api/session.ts] | ||
import { serverSupabaseSession } from '#supabase/server' | ||
|
||
export default defineEventHandler(async (event) => { | ||
return await serverSupabaseSession(event) | ||
}) | ||
``` | ||
|
||
Then call your api route from any vue file: | ||
|
||
```ts [pages/index.vue] | ||
const session = ref(null) | ||
|
||
const fetchSession = async () => { | ||
session.value = await $fetch('/api/session') | ||
} | ||
``` | ||
|
||
Be careful, if you want to call this route on SSR, please read this [section](https://nuxt.com/docs/getting-started/data-fetching#isomorphic-fetch-and-fetch), you must send your browser cookies including your supabase token. | ||
|
||
```ts [pages/index.vue] | ||
const session = ref(null) | ||
|
||
const { data } = await useFetch('/api/session', { | ||
headers: useRequestHeaders(['cookie']) | ||
}) | ||
|
||
session.value = data | ||
``` |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import type { Session } from '@supabase/supabase-js' | ||
import type { Ref } from 'vue' | ||
import { useSupabaseClient } from './useSupabaseClient' | ||
import { useState } from '#imports' | ||
|
||
export const useSupabaseSession = () => { | ||
const supabase = useSupabaseClient() | ||
|
||
const sessionState = useState<Session | null>('supabase_session', () => null) | ||
|
||
// Asyncronous refresh session and ensure user is still logged in | ||
supabase?.auth.getSession().then(({ data: { session } }) => { | ||
if (session) { | ||
if (JSON.stringify(sessionState.value) !== JSON.stringify(session)) { | ||
sessionState.value = session | ||
} | ||
} else { | ||
sessionState.value = null | ||
} | ||
}) | ||
|
||
return sessionState as Ref<Session | null> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import type { Session } from '@supabase/supabase-js' | ||
import type { H3Event } from 'h3' | ||
import { createError } from 'h3' | ||
import { serverSupabaseClient } from '../services/serverSupabaseClient' | ||
|
||
export const serverSupabaseSession = async (event: H3Event): Promise<Session | null> => { | ||
const client = await serverSupabaseClient(event) | ||
|
||
const { data: { session }, error } = await client.auth.getSession() | ||
if (error) { | ||
throw createError({ statusMessage: error?.message }) | ||
} | ||
|
||
event.context._session = session ?? null | ||
|
||
return event.context._session | ||
} |