Lock: reqwest module outdated and breaking serverside rendering

Created on 20 Aug 2016  路  5Comments  路  Source: auth0/lock

Getting a 'window is not defined' error when serverside rendering via react + webpack

When running a webpack build for serverside rendering, the

/Users/davidwells/Scratch/site/node_modules/reqwest/reqwest.js:8
  if (typeof module != 'undefined' && module.exports) module.exports = definition()
                                                                       ^
ReferenceError: window is not defined
    at /Users/davidwells/Scratch/site/node_modules/reqwest/reqwest.js:13:13

image

Lock version ^10.2.1

It looks like this was fixed: https://github.com/ded/reqwest/issues/153 in a later version of reqwest

The node_modules/auth0-js package is using an outdated version of reqwest ^1.1.4. The current latest is at 2.0.5

Can we update this dependency?

Most helpful comment

This issue should not be closed. You cannot import auth0-lock if you have an isomorphic (renders on the server as well) app. Perhaps use https://github.com/matthew-andrews/isomorphic-fetch

This:

if (isClient) {
  var Auth0Lock = require('auth0-lock').default
}

sucks.

Is there another auth0 library I should be using if I am going for an isomorphic render? At least one that does not break server side render?

All 5 comments

Similarly the winchan library is missing some checks to ensure isomorphic/universal compatibility https://github.com/auth0/winchan/blob/master/winchan.js#L21

/Users/davidwells/Scratch/site/node_modules/winchan/winchan.js:21
    var ua = navigator.userAgent;
             ^
ReferenceError: navigator is not defined
    at isInternetExplorer (/Users/davidwells/Scratch/site/node_modules/winchan/winchan.js:21:14)
    at /Users/davidwells/Scratch/site/node_modules/winchan/winchan.js:81:14
    at Object.<anonymous> (/Users/davidwells/Scratch/site/node_modules/winchan/winchan.js:297:3)
    at Module._compile (module.js:435:26)
    at Module._extensions..js (module.js:442:10)
    at Object.require.extensions.(anonymous function) [as .js] (/Users/davidwells/Scratch/site/node_modules/babel-register/lib/node.js:156:7)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:313:12)
    at Module.require (module.js:366:17)
    at require (module.js:385:17)

Fixed this with a conditional require if other folks run into this.

const isClient = typeof window !== 'undefined'
if (isClient) {
  var Auth0Lock = require('auth0-lock').default
}

Full code:

import { EventEmitter } from 'events'
import { isTokenExpired } from './jwtHelper'
import LogoImg from '../assets/images/logo.png'

const isClient = typeof window !== 'undefined'
if (isClient) {
  var Auth0Lock = require('auth0-lock').default
}

export default class AuthService extends EventEmitter {
  constructor (clientId, domain) {
    super()
    if (!isClient) {
      return false
    }
    // Configure Auth0
    this.lock = new Auth0Lock(clientId, domain, { // eslint-disable-line
      theme: {
        logo: LogoImg,
        primaryColor: '#000'
      },
    })
    // Add callback for lock `authenticated` event
    this.lock.on('authenticated', this._doAuthentication.bind(this))
    // Add callback for lock `authorization_error` event
    this.lock.on('authorization_error', this._authorizationError.bind(this))
    // binds login functions to keep this context
    this.login = this.login.bind(this)
  }

  _doAuthentication (authResult) {
    // Saves the user token
    this.setToken(authResult.idToken)
    // Async loads the user profile data
    this.lock.getProfile(authResult.idToken, (error, profile) => {
      if (error) {
        console.log('Error loading the Profile', error)
      } else {
        this.setProfile(profile)
      }
    })
  }

  _authorizationError (error) {
    // Unexpected authentication error
    console.log('Authentication Error', error)
  }

  login () {
    // Call the show method to display the widget.
    this.lock.show()
  }

  loggedIn () {
    // Checks if there is a saved token and it's still valid
    const token = this.getToken()
    return !!token && !isTokenExpired(token)
  }

  setProfile (profile) {
    // Saves profile data to isClient && window.localStorage
    isClient && window.localStorage.setItem('profile', JSON.stringify(profile))
    // Triggers profile_updated event to update the UI
    this.emit('profile_updated', profile)
  }

  getProfile () {
    // Retrieves the profile data from isClient && window.localStorage
    const profile = isClient && window.localStorage.getItem('profile')
    return profile ? JSON.parse(isClient && window.localStorage.profile) : {}
  }

  setToken (idToken) {
    // Saves user token to isClient && window.localStorage
    isClient && window.localStorage.setItem('id_token', idToken)
  }

  getToken () {
    // Retrieves the user token from isClient && window.localStorage
    return isClient && window.localStorage.getItem('id_token')
  }

  logout () {
    // Clear user token and profile data from isClient && window.localStorage
    isClient && window.localStorage.removeItem('id_token')
    isClient && window.localStorage.removeItem('profile')
  }
}

@DavidWells I'm guessing you added the if block inside the constructor too? (Just in case people miss it. ;) )

This issue should not be closed. You cannot import auth0-lock if you have an isomorphic (renders on the server as well) app. Perhaps use https://github.com/matthew-andrews/isomorphic-fetch

This:

if (isClient) {
  var Auth0Lock = require('auth0-lock').default
}

sucks.

Is there another auth0 library I should be using if I am going for an isomorphic render? At least one that does not break server side render?

Was this page helpful?
0 / 5 - 0 ratings