DEV Community

Maurício Andrade Albuquerque
Maurício Andrade Albuquerque

Posted on

Implementing OpenID Connect (OIDC) Authentication with Nuxt 3, without saving the token in sessionStorage or localstorage

This tutorial use as base:
[https://dev.to/taikio/implementing-openid-connect-oidc-authentication-with-nuxt-3-2fa4]
You need to read the tutorial above to understand this tutorial here.
This tutorial here did a change to don't save the token in the localstorage or sessionstorage.
The token is only saved in the pinia .
Another change was about change to use Universal render (nuxt's default).

nuxt.config.ts

//remove ssr: false
Enter fullscreen mode Exit fullscreen mode

With this change you need take care about only call the oidc-client-ts in the client-side, because nuxt will use server and client render (nuxt's default).

auth-service.ts

import {InMemoryWebStorage} from 'oidc-client-ts';
import { useAuth } from '@/stores/auth';

... code here

//change the line below
userStore: new WebStorageStateStore({ store: new InMemoryWebStorage() }),

... code here

this.userManager = new UserManager(settings);
this.userManager.events.addUserLoaded((user) => {
      const authStore = useAuth();
      authStore.setUpUserCredentials(user);
    });
Enter fullscreen mode Exit fullscreen mode

The code above change the store to memory, then you don't save the user and token in the sessionStorage or localStorage.
If you use getUser the user is not returned, then you need use Pinia to store and get the User and token.
The code addUserLoaded will be used to refresh the token, and will be called automatically by oidc-client-ts.

auth-middleware.global.ts

import { useAuth } from '@/stores/auth';

export default defineNuxtRouteMiddleware(async (to, _from) => {

if (process.server) {
    return
}

const authStore = useAuth();
const {isLoggedIn} = authStore;

if (!authFlowRoutes.includes(to.path) && !isLoggedIn) {
    services.$auth.signInRedirect();
}
Enter fullscreen mode Exit fullscreen mode

The code above you only render in the client, returning when the process is on the server. Nuxt run the middleware on the client and server, and with this modification will run only on the client.

Then you will do a signIn when the User is not in the Pinia yet.

auth.vue

<script setup>
import { useServices } from '~/composables/useServices';
import { onMounted } from 'vue';
import { useAuth } from '@/stores/auth';

onMounted( async () => {
    await authenticateOidc();
});

await services.$auth.signInCallback().then(user=> {
        if(user) {
          authStore.setUpUserCredentials(user);
        }
      });
Enter fullscreen mode Exit fullscreen mode

The code above is called after the signin is done and in the return you are in the auth.vue page.
You need to call the code inside onMounted, because you need to render it on the client side.
After siginCalllback you store the User in the Pinia.

The last change is to call logout.vue inside onMounted, to run it on the client side.

Top comments (1)

Collapse
 
victorneves profile image
Victor Neves

Hi Maurício

This version also doesn't work with SSR as the original post, right?

Thanks