Microsoft-authentication-library-for-js: Library does not work on nuxt application

Created on 7 Aug 2019  路  11Comments  路  Source: AzureAD/microsoft-authentication-library-for-js

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report  
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Other... Please describe:

Browser:

  • [x] Chrome version XX
  • [ ] Firefox version XX
  • [ ] IE version XX
  • [ ] Edge version XX
  • [ ] Safari version XX

Library version


Library version: 1.1.1

Current behavior


REPRO: https://codesandbox.io/s/codesandbox-nuxt-dhsud?fontsize=14

The nuxt app crashes when trying to instantiate msal with the following error.

The cache location provided is not valid. Provided value: sessionStorage. Possible values are: localStorage, sessionStorage.

Expected behavior


An error should not be thrown.

Minimal reproduction of the problem with instructions


Create a nuxt application and add the following code anywhere in the app e.g. created hook

var msalConfig = {
    auth: {
        clientId: 'your_client_id'
    }
};

var msalInstance = new Msal.UserAgentApplication(msalConfig);

msalInstance.handleRedirectCallback((error, response) => {
    // handle redirect response or error
});
compatibility question

All 11 comments

Hi @noobling I have an example working in nuxt, it's from the previous version but if I have time today I update the code to the current version. https://github.com/jeverduzco/nuxtjs-azure-ad-b2c-login

@noobling thanks for sharing your issue

can you try adding this to your config, it should not be necessary but I am curious if it will fix it

const msalConfig = { 
    auth: {
         clientId: 'yourclientId'
    },
    cache: { 
       cacheLocation: 'sessionStorage'
     }
};

@DarylThayil Updated code sample with that code it doesn't make a difference https://codesandbox.io/s/codesandbox-nuxt-dhsud?fontsize=14

@jeverduzco approach might fix it by wrapping msal in a class because I think the root cause is related to this. I will try it out and let you know.

Stack trace
image

Wrapping the initialisation of msal in a class works

The problem is that nuxt does server-side rendering, and msal will not work when server-side rendered, as there is no window. The error handling for instantiating the Storage class naively assumes that any uncaught error is the result of an invalid cacheLocation string, but in this case the error is occurring because window is undefined. I'll create a ticket to improve this.

@noobling Can you share the code you wrote to make it work? Thanks!

Yeah, that makes sense. Will provide a working example for nuxt/vue when I get the time but here is the current auth code.

import * as Msal from 'msal'

export default class AuthService {
  constructor() {
    this.auth = new Msal.UserAgentApplication({
      auth: {
        clientId: process.env.CLIENT_ID, // This is your client ID
        authority: process.env.APP_AUTHORITY,
      },
      cache: {
        cacheLocation: 'sessionStorage',
      },
    })
  }

  login() {
    var loginRequest = {
      scopes: ['user.read'], // optional Array<string>
    }

    this.auth.loginPopup(loginRequest).then(
      response => {},
      error => {}
    )
  }
}

Then initialise that class in the plugin file and add it to Vue instance

import Vue from 'vue'
import AuthService from '../services/authService'

Vue.prototype.$auth = new AuthService()

closing, will address incorrect error message in #916

will also look at adding a sample that hows how to handle isomorphic apps using msal js

I have thought about this problem a bit more I don't think fundamentally we can use msal js for universal apps without doing some hacking. The only maintainable way would be to use the http api https://docs.microsoft.com/en-us/azure/active-directory/develop/v1-protocols-oauth-code to write code that will be able to run in both client and server-side.

The issue lies in the very first request the user makes to fetch the nuxt app. Since initial loads are rendered serverside for performance and SEO reasons we can't authenticate the user because msal does not run serverside. This means we can't fetch any sensitive data on the initial load. To fix this we would have to store user state in the server...

Let me know your thoughts

@noobling Correct, currently MSAL.js cannot be rendered server-side, so if you have data that requires an access token, you'll need to either acquire an access token another way (e.g. passport-azure-ad), or defer rendering of those components to the client.

A Node wrapper for MSAL is on our roadmap, and isomorphic applications is definitely something we'd like to support.

For anyone using nuxt who wants a simple solution for auth Ive extended the nuxt auth library look at this example for how to use it. https://github.com/noobling/auth-module/tree/dev/examples/demo

Was this page helpful?
0 / 5 - 0 ratings