Auth in Nuxt 3: Logging in and Logging Out (2 of 4)

In this second article, we’ll go over how to use Supabase and Github to log our users in and out of our application.

Michael Thiessen
Nuxt 3

Mastering Nuxt 3 course is here!

Get notified when we release new tutorials, lessons, and other expert Nuxt content.

Click here to view the Nuxt 3 course

The first step in implementing auth in our Nuxt 3 app is to log our users in — and then log them out.

In this series, we’re covering how to use Supabase with Nuxt 3 to add auth to our apps:

  1. Setting up Supabase Auth with Nuxt 3
  2. Logging in and out with Github 👈 we’re here
  3. Protecting Routes
  4. Protecting Server Routes

In this second article, we’ll go over how to use Supabase and Github to log our users in and out of our application.

Here is what we’ll cover in this article:

  1. Authentication vs. Authorization
  2. Using Github for Authorization
  3. Logging in
  4. Logging out
  5. Displaying User Info

Authentication vs. Authorization

Before we get too far, I want to clarify the distinction between authentication and authorization.

(It also doesn’t help that they both shorten to “auth”, so it’s not always clear which one we’re referring to!)

Here are quick definitions:

  • Authentication — this is about identity, about proving that you are who you say you are.
  • Authorization — this is about access, about determining who can do what in your application.

We’re only going to cover authentication here. Authorization is a much deeper subject that can involve role-based access, row-level security, and digging deeper into postgres.

If you’re interested in this, Supabase has some great tutorials on the subject.

Using Github for Authentication

Oauth

Managing users, along with resetting passwords and everything else that goes into that, can be a huge pain.

So why bother?

Instead, we can leverage OAuth and simply piggy-back on the account systems that Github has already created. This also means our users don’t have to create another account just to use our app.

This is why we set up Github as an OAuth provider in the previous article.

Logging In

Here’s the key snippet we need to login a user:

const supabase = useSupabaseAuthClient();

const login = async () => {
  const { error } = await supabase.auth.signInWithOAuth({
    provider: 'github',
  });

  if (error) {
    console.error(error);
  }
};

We get our auth client from Supabase, then use it to sign in. In the provider field we can specify any OAuth provider that we have configured.

In our case, we only have Github configured, so that’s what we choose.

Logging Out

Getting someone logged in is only half the battle. We also need to give them a way to log out!

This logout method mirrors what we just did for logging in:

const supabase = useSupabaseAuthClient();

const logout = async () => {
  const { error } = await supabase.auth.signOut();

  if (error) {
    console.error(error);
    return;
  }

  await navigateTo('/login');
};

However, at the end of the method we use the navigateTo method that’s built-in to Nuxt 3 in order to redirect back to the login page.

We do this immediately for two reasons:

  1. This makes it easy for the user to log back in if they need
  2. The user shouldn’t have access to the current page if they’re logged out, so we kick them out of the application

In the next article in this series we’ll see how to use route middleware to lock down pages in our application, only allowing users who have logged in.

This works by checking if the user is logged in before rendering the page. The problem when we log out is that we’re already on the rendered page, so the route middleware doesn’t get called. Redirecting back to the login page solves this issue.

Displaying User Info

We want to show some visual indication that a user is logged in, along with giving some relevant controls.

Here, we can implement a basic UserCard component that shows the users Github avatar, name, and a button to logout:

<template>
  <div
    v-if="user"
    class="rounded p-3 flex items-center space-x-3 bg-white"
  >
    <img
      class="rounded-full w-12 h-12 border-2 border-blue-400"
      :src="profile"
    />
    <div class="text-right">
      <div class="font-medium">{{ name }}</div>
      <button
        class="text-sm underline text-slate-500"
      >
        Log out
      </button>
    </div>
  </div>
</template>

<script setup lang="ts">
const user = useSupabaseUser();

const name = computed(
  () => user?.value.user_metadata.full_name
);
const profile = computed(
  () => user?.value.user_metadata.avatar_url
);
</script>

We can grab the user object that Github returns from the [useSupabaseUser composable](https://supabase.nuxtjs.org/usage/composables/use-supabase-user).

Then, we make a couple computed refs to easily access our name and profile properties because the full, nested object path is quite long and cumbersome.

I also decided to make this component super simple to use.

Because it requires no props, slots, or events, we can drop it in wherever we need. And, it only renders if we actually have a user logged in. If no one is logged in, user is null and the component doesn’t render anything!

Wrapping Up

Now we have a Nuxt app where we can log users in and out — and see their info displayed in a nice little UserCard component.

But we can still access our entire app, even if we’re not logged in.

The next article in this series shows how we can use route middleware in order to protect specific routes, ensuring that only users who are logged in can access them.

Next Article: Protecting Routes

Michael Thiessen
Michael is a passionate full time Vue.js and Nuxt.js educator. His weekly newsletter is sent to over 11,000 Vue developers, and he has written over a hundred articles for his blog and VueSchool.

Follow MasteringNuxt on