---
title: "Authentication"
description: "Authenticate your user thanks to the PKCE Oauth protocol that enables secure exchange of refresh and access tokens between an application and the authorization server"
canonical_url: "https://supabase.nuxtjs.org/getting-started/authentication"
---
# Authentication

> Authenticate your user thanks to the PKCE Oauth protocol that enables secure exchange of refresh and access tokens between an application and the authorization server

With the default options, the module requires a log-in page and a confirm page to handle the [PKCE authorization code flow](https://supabase.com/docs/guides/resources/glossary#pkce). If you want to understand how it works under the hood, you can read this [section](https://supabase.com/docs/guides/auth/server-side-rendering#understanding-the-authentication-flow).

All you need to do is to create a `login.vue` and `confirm.vue` page in the `pages` folder.

<tip>

For advanced users who want to implement the auth behaviour themselves, you can disable or override the [redirect options](https://supabase.nuxtjs.org/getting-started/introduction#redirect).

</tip>

## Log-in page - `/login`

Each time a user is trying to access a page that needs authentication, he will automatically be redirected to the configured log in page. If you want to allow access to "public" page, you just need to add them in the [exclude](https://supabase.nuxtjs.org/getting-started/introduction#redirectoptions) redirect option. Alternatively, you can enable the redirect only for certain routes using the [include](https://supabase.nuxtjs.org/getting-started/introduction#redirectoptions) redirect option.

<warning>

Ensure to activate the authentication providers you want in the Supabase Dashboard under `Authentication -> Providers`.

</warning>

The log-in page initiates the log-in method(s) you choose from the [available authorization methods](https://supabase.com/docs/reference/javascript/auth-signinwithpassword) provided by Supabase, it could looks like:

```vue [pages/login.vue]
<script setup lang="ts">
const supabase = useSupabaseClient()
const email = ref('')

const signInWithOtp = async () => {
  const { error } = await supabase.auth.signInWithOtp({
    email: email.value,
    options: {
      emailRedirectTo: 'http://localhost:3000/confirm',
    }
  })
  if (error) console.log(error)
}
</script>
<template>
  <div>
    <button @click="signInWithOtp">
      Sign In with E-Mail
    </button>
    <input
      v-model="email"
      type="email"
    />
  </div>
</template>
```

Once the authorization flow is triggered using the `auth` wrapper of the [useSupabaseClient](https://supabase.nuxtjs.org/composables/usesupabaseclient) composable, the session management is handled automatically and the user will be redirected to the page you specify in the redirect option (`/confirm` by default).

## Confirm page - `/confirm`

The confirmation page receives the supabase callback which contains session information. The supabase client automatically detects and handles this, and once the session is confirmed the user value will automatically be updated. From there you can redirect to the appropriate page.

<tip>

The redirect URL must be configured in your Supabase dashboard under `Authentication -> URL Configuration -> Redirect URLs`.

</tip>

```vue [pages/confirm.vue]
<script setup lang="ts">
const user = useSupabaseUser()

watch(user, () => {
  if (user.value) {
      // Redirect to protected page
      return navigateTo('/')
  }
}, { immediate: true })
</script>

<template>
  <div>Waiting for login...</div>
</template>
```

### Redirect path

You can easily handle redirection to the initial requested route after login using the [`useSupabaseCookieRedirect`](https://supabase.nuxtjs.org/composables/usesupabasecookieredirect) composable and the [`saveRedirectToCookie`](https://supabase.nuxtjs.org/getting-started/introduction#redirectoptions) option.

By setting the `saveRedirectToCookie` option to `true`, the module will automatically save the current path to a cookie when the user is redirected to the login page. When the user logs in, you can then retrieve the saved path from the cookie and redirect the user to it on the [`/confirm`](https://supabase.nuxtjs.org/getting-started/authentication#confirm-page-confirm) page:

```vue [pages/confirm.vue]
<script setup lang="ts">
const user = useSupabaseUser()
const redirectInfo = useSupabaseCookieRedirect()

watch(user, () => {
  if (user.value) {
    // Get redirect path, and clear it from the cookie
    const path = redirectInfo.pluck()
    // Redirect to the saved path, or fallback to home
    return navigateTo(path || '/') 
  }
}, { immediate: true })
</script>

<template>
  <div>Waiting for login...</div>
</template>
```

<tip>

If you want to manually set the redirect path, you can do so by disabling [`saveRedirectToCookie`](https://supabase.nuxtjs.org/getting-started/introduction#redirectoptions), and then set the value using the [`useSupabaseCookieRedirect`](https://supabase.nuxtjs.org/composables/usesupabasecookieredirect) composable directly.

</tip>

## Reset Password

You can easily handle password reset request for the user. The flow consist of 2 steps:

<steps>

#### Allow the user to login via the password reset link. When the user clicks the reset link in the email they are redirected back to your application.

```vue [pages/password/reset.vue]
<script setup lang="ts">
const supabase = useSupabaseClient()
const email = ref('')

const requestResetPassword = async () => {
  const { data, error } = await supabase.auth.resetPasswordForEmail(email.value, {
    redirectTo: 'https://example.com/password/update',
  })
  if (error) console.log(error)
}
</script>

<template>
  <div>
    <input
      v-model="email"
      type="email"
    />
    <button @click="requestResetPassword">
      Reset Password
    </button>
  </div>
</template>
```

<tip>

You can configure the URL that the user is redirected to with the `redirectTo` parameter.

</tip>

#### After the user has been redirected successfully, prompt them for a new password and call `updateUser()`

```vue [pages/password/update.vue]
<script setup lang="ts">
const supabase = useSupabaseClient()
const newPassword = ref('')

const updateUserPassword = async () => {
  const { data, error } = await supabase.auth.updateUser({
    password: newPassword.value
  })
  if (error) console.log(error)
}
</script>

<template>
  <div>
    <input
      v-model="newPassword"
      type="password"
    />
    <button @click="updateUserPassword">
      Update Password
    </button>
  </div>
</template>
```

</steps>

You can also watch for the event `PASSWORD_RECOVERY` that will be emitted when the password recovery link is clicked. You can use `onAuthStateChange()` to listen and invoke a callback function on these events.

```vue [pages/password/update.vue]
<script setup lang="ts">
const supabase = useSupabaseClient()
const password = generateRandomPassword()

watch(newPassword, () => {
  supabase.auth.onAuthStateChange(async (event, session) => {
    if (event == "PASSWORD_RECOVERY") {
      const { data, error } = await supabase.auth
        .updateUser({ password })

      if (data) alert("Password updated successfully!")
      if (error) alert("There was an error updating your password.")
    }
  })
</script>
```

If you want to learn more about it, you can read this [section](https://supabase.com/docs/reference/javascript/auth-resetpasswordforemail).


## Sitemap

See the full [sitemap](https://supabase.nuxtjs.org/sitemap.md) for all pages.
