Tobias Etter
Tobias Etter

Reputation: 774

How to use auth0 with angular universal

I tried to add server side rendering for my angular 2+ application in order to use SEO.

Now I get a problem because of using auth0-js.

Console output is the following:

ERROR { TypeError: Cannot read property 'location' of undefined at WebAuth.parseHash (C:\Dev\frontend\node_modules\auth0-js\src\web-auth\index.js:138:53) at e.handleAuthentication (C:\Dev\frontend\dist\server.js:8:523298) at new e (C:\Dev\frontend\dist\server.js:8:161974) at createClass (C:\Dev\frontend\node_modules\@angular\core\bundles\core.umd.js:12509:20) at createDirectiveInstance (C:\Dev\frontend\node_modules\@angular\core\bundles\core.umd.js:12 ) at createViewNodes (C:\Dev\frontend\node_modules\@angular\core\bundles\core.umd.js:13815:53) at createRootView (C:\Dev\frontend\node_modules\@angular\core\bundles\core.umd.js:13704:5) at Object.createProdRootView [as createRootView] (C:\Dev\frontend\node_modules\@angular\core\ s\core.umd.js:14397:12) at ComponentFactory_.create (C:\Dev\frontend\node_modules\@angular\core\bundles\core.umd.js:1 6) at ComponentFactoryBoundToModule.create (C:\Dev\frontend\node_modules\@angular\core\bundles\c d.js:4070:29) __zone_symbol__currentTask: ZoneTask { _zone: Zone { _properties: [Object], _parent: [Object], _name: 'angular', _zoneDelegate: [Object] }, runCount: 0, _zoneDelegates: null, _state: 'notScheduled', type: 'microTask', source: 'Promise.then', data: undefined, scheduleFn: undefined, cancelFn: null, callback: [Function], invoke: [Function] } } Unhandled Promise rejection: Cannot read property 'location' of undefined ; Zone: <root> ; Task: Promise.then ; Value: { TypeError: Cannot read property 'location' of undefined at WebAuth.parseHash (C:\Dev\frontend\node_modules\auth0-js\src\web-auth\index.js:138:53) at e.handleAuthentication (C:\Dev\frontend\dist\server.js:8:523298) at new e (C:\Dev\frontend\dist\server.js:8:161974) at createClass (C:\Dev\frontend\node_modules\@angular\core\bundles\core.umd.js:12509:20) at createDirectiveInstance (C:\Dev\frontend\node_modules\@angular\core\bundles\core.umd.js:12 354:37) at createViewNodes (C:\Dev\frontend\node_modules\@angular\core\bundles\core.umd.js:13815:53) at createRootView (C:\Dev\frontend\node_modules\@angular\core\bundles\core.umd.js:13704:5) at Object.createProdRootView [as createRootView] (C:\Dev\frontend\node_modules\@angular\core\ bundles\core.umd.js:14397:12) at ComponentFactory_.create (C:\Dev\frontend\node_modules\@angular\core\bundles\core.umd.js:1 1299:46) at ComponentFactoryBoundToModule.create (C:\Dev\frontend\node_modules\@angular\core\bundles\c ore.umd.js:4070:29) __zone_symbol__currentTask: ZoneTask { _zone: Zone { _properties: {}, _parent: null, _name: '<root>', _zoneDelegate: [Object] }, runCount: 0, _zoneDelegates: null, _state: 'notScheduled', type: 'microTask', source: 'Promise.then', data: undefined, scheduleFn: undefined, cancelFn: null, callback: [Function], invoke: [Function] } } TypeError: Cannot read property 'location' of undefined at WebAuth.parseHash (C:\Dev\frontend\node_modules\auth0-js\src\web-auth\index.js:138:53) at e.handleAuthentication (C:\Dev\frontend\dist\server.js:8:523298) at new e (C:\Dev\frontend\dist\server.js:8:161974) at createClass (C:\Dev\frontend\node_modules\@angular\core\bundles\core.umd.js:12509:20) at createDirectiveInstance (C:\Dev\frontend\node_modules\@angular\core\bundles\core.umd.js:12 354:37) at createViewNodes (C:\Dev\frontend\node_modules\@angular\core\bundles\core.umd.js:13815:53) at createRootView (C:\Dev\frontend\node_modules\@angular\core\bundles\core.umd.js:13704:5) at Object.createProdRootView [as createRootView] (C:\Dev\frontend\node_modules\@angular\core\ bundles\core.umd.js:14397:12) at ComponentFactory_.create (C:\Dev\frontend\node_modules\@angular\core\bundles\core.umd.js:1 1299:46) at ComponentFactoryBoundToModule.create (C:\Dev\frontend\node_modules\@angular\core\bundles\c ore.umd.js:4070:29)

I used the default code from auth0 example:

public handleAuthentication(): void {
this.auth0.parseHash((err, authResult) => {
  if (authResult && authResult.accessToken && authResult.idToken) {
    window.location.hash = '';
    this.setSession(authResult);
    this.router.navigate(['/']);
  } else if (err) {
    this.router.navigate(['/']);
    console.log(err);
    alert(`Error: ${err.error}. Check the console for further details.`);
  }
});

}

UPDATE:

I added angular universal gotchas to my auth service.

Now I get the following new error as soon as I open localhost:4200:

ERROR { Error: Uncaught (in promise): Error
at resolvePromise (C:\Dev\frontend\node_modules\zone.js\dist\zone-node.js:824:31)
at resolvePromise (C:\Dev\frontend\node_modules\zone.js\dist\zone-node.js:795:17)
at C:\Dev\frontend\node_modules\zone.js\dist\zone-node.js:873:17
at ZoneDelegate.invokeTask (C:\Dev\frontend\node_modules\zone.js\dist\zone-node.js:425:31)
at Object.onInvokeTask (C:\Dev\frontend\node_modules\@angular\core\bundles\core.umd.js:4783:33)
at ZoneDelegate.invokeTask (C:\Dev\frontend\node_modules\zone.js\dist\zone-node.js:424:36)
at Zone.runTask (C:\Dev\frontend\node_modules\zone.js\dist\zone-node.js:192:47)
at drainMicroTaskQueue (C:\Dev\frontend\node_modules\zone.js\dist\zone-node.js:602:35)
at ZoneTask.invokeTask (C:\Dev\frontend\node_modules\zone.js\dist\zone-node.js:503:21)
at Server.ZoneTask.invoke (C:\Dev\frontend\node_modules\zone.js\dist\zone-node.js:488:48) rejection: { [Error]
 __zone_symbol__currentTask:
  ZoneTask {
    _zone: [Object],
    runCount: 0,
    _zoneDelegates: null,
    _state: 'notScheduled',
    type: 'microTask',
    source: 'Promise.then',
    data: undefined,
    scheduleFn: undefined,
    cancelFn: null,
    callback: [Function],
    invoke: [Function] } }, promise: ZoneAwarePromise {
 __zone_symbol__state: 0,
 __zone_symbol__value: { [Error] __zone_symbol__currentTask: [Object] } }, zone: Zone {
 _properties: { isAngularZone: true },
 _parent:
  Zone {
    _properties: {},
    _parent: null,
    _name: '<root>',
    _zoneDelegate: [Object] },
 _name: 'angular',
 _zoneDelegate:
  ZoneDelegate {
    _taskCounts: [Object],
    zone: [Circular],
    _parentDelegate: [Object],
    _forkZS: null,
    _forkDlgt: null,
    _forkCurrZone: [Object],
    _interceptZS: null,
    _interceptDlgt: null,
    _interceptCurrZone: [Object],
    _invokeZS: [Object],
    _invokeDlgt: [Object],
    _invokeCurrZone: [Circular],
    _handleErrorZS: [Object],
    _handleErrorDlgt: [Object],
    _handleErrorCurrZone: [Circular],
    _scheduleTaskZS: [Object],
    _scheduleTaskDlgt: [Object],
    _scheduleTaskCurrZone: [Circular],
    _invokeTaskZS: [Object],
    _invokeTaskDlgt: [Object],
    _invokeTaskCurrZone: [Circular],
    _cancelTaskZS: [Object],
    _cancelTaskDlgt: [Object],
    _cancelTaskCurrZone: [Circular],
    _hasTaskZS: [Object],
    _hasTaskDlgt: [Object],
    _hasTaskDlgtOwner: [Circular],
    _hasTaskCurrZone: [Circular] } }, task: ZoneTask {
 _zone:
  Zone {
    _properties: [Object],
    _parent: [Object],
    _name: 'angular',
    _zoneDelegate: [Object] },
 runCount: 0,
 _zoneDelegates: null,
 _state: 'notScheduled',
 type: 'microTask',
 source: 'Promise.then',
 data: undefined,
 scheduleFn: undefined,
 cancelFn: null,
 callback: [Function],
 invoke: [Function] } }

Does someone have an idea how to solve this problem?

Many thanks

Upvotes: 0

Views: 679

Answers (1)

David
David

Reputation: 34435

window, document and other browser objects are not defiend when on server side.

You can add platform specific code which executes only if you are server side or client side.

https://github.com/angular/universal#universal-gotchas

Note: I haven't see the example code, but I'm not even sure that resettign the hash is useful here if ou are navigating to "/" after anyway

Upvotes: 1

Related Questions