Skip to content
This repository has been archived by the owner on Feb 9, 2019. It is now read-only.

angular2-jwt / SystemJS load issue #13

Closed
jek-bao-choo opened this issue Feb 6, 2016 · 25 comments
Closed

angular2-jwt / SystemJS load issue #13

jek-bao-choo opened this issue Feb 6, 2016 · 25 comments

Comments

@jek-bao-choo
Copy link

Hi @chenkie

I'm attempting to use Auth0 with my new Angular2 project. I'm new to SystemJS.
I'm following your example auth0-angular2. My new project is like Angular.io Tour of Heroes.

Here is the problem: My module angular2-jwt couldn't load. I couldn't use it in my main.ts.

Choopage's System.JS config
choopage

Chenkie's System.JS config
chenkie

I can do it like yours example but my TOH app would fail.
So what should I do to make my SystemJS right so I can use Angular2-JWT?
Or do you have an example of Angular.io's TOH using Auth0?

@set321go
Copy link

set321go commented Feb 7, 2016

I'm having essentially the same problem. I've tried a few different things but they all result in Unexpected Token < if I do it the example way that error comes out of app/main

System.config({
  defaultJSExtensions: true,
  packages: {
    "/angular2-jwt": {
      "defaultExtension": "js"
    }
  },
  map: {
    "angular2-jwt": "node_modules/angular2-jwt/angular2-jwt"
  }
 });
.....
System.import('app/main').catch(console.log.bind(console));

if you try and define two packages it comes out of angular2-jwt

System.config({
  packages: {
    app: {
      format: 'register',
      defaultExtension: 'js'
    },
    "/angular2-jwt": {
      "defaultExtension": "js"
    }
  },
  map: {
    "angular2-jwt": "node_modules/angular2-jwt/angular2-jwt"
  }
});
System.import('app/main')
    .then(null, console.error.bind(console));

If i get rid of those paths in the package format which look nasty anyway

System.config({
  packages: {
    app: {
      format: 'register',
      defaultExtension: 'js'
    },
    "angular2-jwt": {
      "defaultExtension": "js"
    }
  },
  map: {
    "angular2-jwt": "node_modules/angular2-jwt"
  }
});
System.import('app/main')
    .then(null, console.error.bind(console));

Now i get undefined is not an object (evaluating 'injector.getOptional') in my main.js so that might be actually loading it (further investigation required).

When you try and load it in using the script tag you get the Multiple anonymous System.register error, but you can hack the script to add a bundle name System.register("angular2-jwt" which results in you getting the Unexpected token < as above.

@chenkie
Copy link
Contributor

chenkie commented Feb 8, 2016

You can try mapping directly to angular2-jwt.js.

System.config({
  defaultJSExtensions: true,
  packages: {
    app: {
      format: 'register',
      defaultExtension: 'js'
    },       
  },
  map: {
    "angular2-jwt": "node_modules/angular2-jwt/angular2-jwt.js"
  }
});
System.import('app/main').then(null, console.error.bind(console));

Let me know if that works for you. Also, don't forget to bring in angular2/http.dev.js if you haven't already :)

@jek-bao-choo
Copy link
Author

Hi @chenkie

The snippet above is not working. My code is following angular.io official Tour of Heroes setup in using Systemjs.

Added your snippet and also http.dev.js

screen shot 2016-02-09 at 1 18 49 am

screen shot 2016-02-09 at 1 17 28 am

screen shot 2016-02-09 at 1 23 06 am

Also those that @set321go have tried, I tried too. It doesn't work yup.

Could you build a quickstart Angular.io TOH (https://angular.io/docs/ts/latest/quickstart.html) and add Auth0 login to it?

@set321go
Copy link

set321go commented Feb 8, 2016

Made some progress this morning I pulled down angular2-jwt and bumped the versions for angular and zone (p.s. @choopage angular2 beta 3 requires zone 5.11 i believe) rebuilt it and installed it into my project. Now i can get a stripped down app to start without errors

System.config({
  packages: {
    app: {
      format: 'register',
      defaultExtension: 'js'
    },
    "angular2-jwt": {
      "defaultExtension": "js"
    }
  },
  map: {
    "angular2-jwt": "node_modules/angular2-jwt"
  }
});
System.import('app/main')
    .then(null, console.error.bind(console));

then my main.ts

import {bootstrap}    from 'angular2/platform/browser';
import {provide} from "angular2/core";
import {AppComponent} from './app.component';
import {ROUTER_PROVIDERS} from 'angular2/router';
import {HTTP_PROVIDERS, Http} from 'angular2/http';
import {AuthHttp, AuthConfig} from "angular2-jwt/angular2-jwt";
import {Auth0Service} from "./auth.service";

bootstrap(AppComponent, [
    HTTP_PROVIDERS,
    ROUTER_PROVIDERS,
    provide(AuthHttp, {
        useFactory: (http) => {
            return new AuthHttp(new AuthConfig(), http);
        },
        deps: [Http]
    }),
    Auth0Service
]);

my app.component.ts looks pretty similar to the example one so i'm not going to show it here.

Auth0Service.ts

import {Injectable} from "angular2/core";
import {HTTP_PROVIDERS, Http} from 'angular2/http';
import {tokenNotExpired} from "angular2-jwt/angular2-jwt";
import {AuthHttp, AuthConfig, tokenNotExpired, JwtHelper} from 'angular2-jwt';

@Injectable()
export class Auth0Service {
    lock: Auth0Lock = new Auth0Lock('myclientid', 'my domain');
    //jwtHelper: JwtHelper = new JwtHelper();

    login() {
        this.lock.show((err: string, profile: string, id_token: string) => {

            if (err) {
                throw new Error(err);
            }

            localStorage.setItem('profile', JSON.stringify(profile));
            localStorage.setItem('id_token', id_token);

        });
    }

    logout() {
        localStorage.removeItem('profile');
        localStorage.removeItem('id_token');
    }

    loggedIn() {
        return tokenNotExpired();
    }
} 

This works. The problem seem's to be JwtHelper() if I uncomment this line //jwtHelper: JwtHelper = new JwtHelper(); it fails.

@chenkie
Copy link
Contributor

chenkie commented Feb 8, 2016

What error does it give you if you uncomment JwtHelper?

@set321go
Copy link

set321go commented Feb 8, 2016

Our favourite!

    SyntaxError: Unexpected token '<'
    Evaluating http://localhost:3000/node_modules/angular2-jwt
    Error loading http://localhost:3000/app/main.js
error
runangular2-polyfills.js:1242
zoneBoundFnangular2-polyfills.js:1219
lib$es6$promise$$internal$$tryCatchangular2-polyfills.js:467
lib$es6$promise$$internal$$invokeCallbackangular2-polyfills.js:479
lib$es6$promise$$internal$$publishangular2-polyfills.js:450
lib$es6$promise$$internal$$publishRejectionangular2-polyfills.js:400
(anonymous function)angular2-polyfills.js:122
runangular2-polyfills.js:1242
zoneBoundFnangular2-polyfills.js:1219
lib$es6$promise$asap$$flushangular2-polyfills.js:261

@set321go
Copy link

set321go commented Feb 8, 2016

Which is really weird because JwtHelper has an empty constructor. I tried wiring it up using the injector but I get the same error. It could be this is the first time it actually tries to load something from the jwt module.

@jek-bao-choo
Copy link
Author

Hi @chenkie

Thank you for looking into this. @set321go and I are having the same problem despite many tries.

    SyntaxError: Unexpected token '<'
    Evaluating http://localhost:3000/node_modules/angular2-jwt
    Error loading http://localhost:3000/app/main.js

Our favourite error message.

@set321go I updated my project to ng2 beta 3 zone 5.11. Thanks for pointing this out. I missed it.

@chenkie my Tour of Heroes repo with Auth0 can be found here https://github.com/choopage/angular2-tour-of-heroes/tree/auth0

Could you lend me a hand by understanding why Auth0 and TOH aren't going together in that repo?
Did I miss anything?

Cheers,
Jek Bao

@set321go
Copy link

set321go commented Feb 9, 2016

Ok so i got it working. It seems the problem was the import statement. I was just using intellij's auto import without really paying it much attention, seems that's where the problem was.

So using the system.config setup posted above.My main.ts looks like this

import {bootstrap}    from 'angular2/platform/browser';
import {provide} from "angular2/core";
import {AppComponent} from './app.component';
import {ROUTER_PROVIDERS} from 'angular2/router';
import {HTTP_PROVIDERS, Http} from 'angular2/http';
import {AuthHttp, AuthConfig, JwtHelper} from "angular2-jwt/angular2-jwt";
import {Auth0Service} from "./auth.service";

bootstrap(AppComponent, [
    HTTP_PROVIDERS,
    ROUTER_PROVIDERS,
    provide(AuthHttp, {
        useFactory: (http) => {
            return new AuthHttp(new AuthConfig(), http);
        },
        deps: [Http]
    }),
    Auth0Service,
    JwtHelper
]);

Then my auth.service.js looks like this

import {Injectable} from "angular2/core";
import {HTTP_PROVIDERS, Http} from 'angular2/http';
import {tokenNotExpired, JwtHelper} from 'angular2-jwt/angular2-jwt';

@Injectable()
export class Auth0Service {
    lock: Auth0Lock = new Auth0Lock('D1N14G6YmYJFLXRodtGGRVS2JhL842P8', 'gbook.auth0.com');
    constructor(public jwtHelper: JwtHelper) {}

    login() {
        this.lock.show((err: string, profile: string, id_token: string) => {

            if (err) {
                console.log(err);
                throw new Error(err);
            }

            localStorage.setItem('profile', JSON.stringify(profile));
           localStorage.setItem('id_token', id_token);

        });
    }

    logout() {
        localStorage.removeItem('profile');
        localStorage.removeItem('id_token');
    }

    loggedIn() {
        return !this.jwtHelper.isTokenExpired(localStorage.getItem('id_token'));
    }
}

The important part for me was angular2-jwt/angular2-jwt in my ide the typescript imports it as angular2-jwt which at runtime doesn't work.

@chenkie
Copy link
Contributor

chenkie commented Feb 9, 2016

Thanks @set321go. @choopage, does this work for you?

I'm going to put together a sample for this because I'm not sure why it's requiring that you use angular2-jwt/angular2-jwt. You shouldn't need to import like that.

@jek-bao-choo
Copy link
Author

Hi @set321go

I have some questions that I hope you could help me.


  • In your main.ts you have the following code
 bootstrap(AppComponent, [
    HTTP_PROVIDERS,
    ROUTER_PROVIDERS,
    provide(AuthHttp, {
        useFactory: (http) => {
            return new AuthHttp(new AuthConfig(), http);
        },
        deps: [Http]
    }),
    Auth0Service, //@set321go why do we need this? 
    JwtHelper //and this?
]);

  • In your auth.service.ts, have this
lock: Auth0Lock = new Auth0Lock('xxxxxxxxxxxx', 'yyyyyyyyyyy');

Wouldn't you run into issue without having this declare var Auth0Lock?


  • Isn't it weird having to do this import {...} from "angular2-jwt/angular2-jwt"; Like you I am using WebStorm. But I can't seem to understand why it would require angular2-jwt/angular2-jwt twice.

Hi @chenkie

I have couple of questions that I hope you could help me.


  • To use Auth0 with Angular2 we do this in main.ts:
bootstrap(AppComponent, [
    HTTP_PROVIDERS,
    ROUTER_PROVIDERS,
    provide(AuthHttp, {
        useFactory: (http) => {
            return new AuthHttp(new AuthConfig(), http);
        },
        deps: [Http]  //@chenkie what is this doing?
    }),
    Auth0Service,
    JwtHelper
]);

What is that above doing deps: [Http]?


  • Is it alright to expose our Auth0 domain and token publicly for open-source collaboration? Example lock: Auth0Lock = new Auth0Lock('D1N14G6YmY.......', 'gbook.auth0.com');?

Any best practices to recommend for managing Auth0 tokens when collaborating?

Cheers

@set321go
Copy link

The client token in Auth0Lock is part of the client side js so its in the public domain, although it feels like it should be secret.

auth.service.ts is where I have refactored the Auth0 login code out of the app.component.ts so that I could isolate it from the view/template/other code.

In the main.ts everything inside the [] are providers, so basically i'm telling angular to wire up Auth0Service using the injector.

The provide() section where we declare AuthHttp is creating an factory for the AuthHttp instance. Basically by default when you use the injector it creates a singleton/one instance. When you use a factory your telling the injector how to create your instance.

The deps part of the provide is telling the injector that AuthHttp requires an instance of http which were defined earlier when we used HTTP_PROVIDERS

I'm not certain about the declare var Auth0Lock (I think that's declaring a global variable) but I don't plan to use the Auth0Lock outside of my angular app. I would imagine if I had js outside of my angular app that used/needed the lock I would want it to avoid having two lock instances in the same page.

@chenkie
Copy link
Contributor

chenkie commented Feb 10, 2016

declare var Auth0Lock lets us avoid name not found warnings.

The Auth0 client ID is indeed a public token, but this is fine since anyone would be able to see it when they view source on your app. Your Auth0 secret token is the important one to keep hidden on your backend and is what is used to check your JWTs to make sure they're legit.

@set321go
Copy link

What causes those warnings? I have not seen it in the browser console.

@chenkie
Copy link
Contributor

chenkie commented Feb 10, 2016

If you take out declare var Auth0Lock you don't see them?

That line is there to avoid name not found warnings, which happen because there aren't TypeScript typings for Auth0Lock.

@jek-bao-choo
Copy link
Author

@chenkie and @set321go thank you for helping with this issue.
I tried @set321go solution. It worked.
I have updated my ng2 TOH code https://github.com/choopage/angular2-tour-of-heroes/tree/auth0

index.html

<script>
        System.config({
            packages: {
                app: {
                    format: 'register',
                    defaultExtension: 'js'
                },
                "angular2-jwt": {
                    "defaultExtension": "js"
                }
            },
            map: {
                "angular2-jwt": "node_modules/angular2-jwt"
            }
        });
        System.import('app/main').then(null, console.error.bind(console));
    </script>

main.ts

import  {bootstrap} from 'angular2/platform/browser'
import {provide} from "angular2/core";
import {AppComponent} from './app.component'
import {ROUTER_PROVIDERS} from 'angular2/router';
import {HTTP_PROVIDERS, Http} from 'angular2/http';
import {AuthHttp, AuthConfig} from "angular2-jwt/angular2-jwt"; //I am stating it twice
import {Auth0Service} from "./auth0.service";

bootstrap(AppComponent, [
    HTTP_PROVIDERS,
    ROUTER_PROVIDERS,
    provide(AuthHttp, {
        useFactory: (http) => {
            return new AuthHttp(new AuthConfig(), http);
        },
        deps: [Http]
    }),
    Auth0Service
]);

@jbuechs
Copy link

jbuechs commented Mar 9, 2016

I am having the same issue - I have Auth0 working in the sample project but when I try to include it in my project, I get the same error

SyntaxError: Unexpected token '<'
Evaluating http://localhost:3000/node_modules/angular2-jwt
Error loading http://localhost:3000/app/main.js

I tried to clone the git repo included above (https://github.com/choopage/angular2-tour-of-heroes/tree/auth0), but when I do npm start, I get the same unexpected token errors.

@chenkie, you said in one of the comments that you were going to put together a sample... do you have a repo on github or somewhere I could look at it?

@jek-bao-choo
Copy link
Author

I'm waiting for Auth0 to provide a complete tutorial on using Auth0 with angular.io TOH :)

Hope your issue is solved @jbuechs

@chenkie
Copy link
Contributor

chenkie commented Mar 10, 2016

I haven't forgotten about this :) I'll touch base next week.

@grunzmeniroj
Copy link

I too have same problem as @jbuechs .. ..... @choopage and @chenkie any update or demo reppo for solving this issue

@chenkie
Copy link
Contributor

chenkie commented Apr 8, 2016

Hi all, my apologies that this took a long time. I finally have the authentication demo based on Angular 2 Tour of Heroes: https://github.com/auth0-blog/angular2-tour-of-heroes

Please let me know if you have any questions :)

@eshell
Copy link

eshell commented May 31, 2016

if i don't do 'import {service} from "angular2-jwt/angular2-jwt", i keep getting 403 forbidden errors. Now I keep getting "no value accessor for ''" errors

@VikramK
Copy link

VikramK commented Jun 3, 2016

I have the below configuration in my system-config.ts

/***********************************************************************************************

  • User Configuration.
    *********************************************************************************************/
    /
    * Map relative paths to URLs. */
    const map: any = {
    };

/** User packages configuration. */
const packages: any = {
};

////////////////////////////////////////////////////////////////////////////////////////////////
/***********************************************************************************************

  • Everything underneath this line is managed by the CLI.
    **********************************************************************************************/
    const barrels: string[] = [
    // Angular specific barrels.
    '@angular/core',
    '@angular/common',
    '@angular/compiler',
    '@angular/http',
    '@angular/router',
    '@angular/router-deprecated',
    '@angular/platform-browser',
    '@angular/platform-browser-dynamic',

    // Thirdparty barrels.
    'rxjs',

    // App specific barrels.
    'app',
    'app/shared',
    'app/signup',
    'app/+phone',
    'app/+logincode',
    'app/+userhome',
    /** @cli-barrel */
    ];

const cliSystemConfigPackages: any = {
"/angular2-jwt": { defaultExtension: 'js' }
};

barrels.forEach((barrelName: string) => {
cliSystemConfigPackages[barrelName] = { main: 'index' };
});

/** Type declaration for ambient System. */
declare var System: any;

// Apply the CLI SystemJS configuration.
System.config({
map: {
'@angular': 'vendor/@angular',
'rxjs': 'vendor/rxjs',
'main': 'main.js',
"angular2-jwt": "node_modules/angular2-jwt/angular2-jwt.js"
},
packages: cliSystemConfigPackages
});

// Apply the user's configuration.
System.config({ map, packages });

And I import from angular2-jwt as below

import { AuthHttp, tokenNotExpired } from 'angular2-jwt';

But I get the below error:

Error loading http://localhost:4200/node_modules/angular2-jwt/angular2-jwt.js as "angular2-jwt" from http://localhost:4200/app/signup/signup.component.js ; Zone: ; Task: Promise.then ; Value: Error: Error: XHR error (404 Not Found) loading http://localhost:4200/node_modules/angular2-jwt/angular2-jwt.js(…)

@santiim
Copy link

santiim commented Nov 11, 2016

Hello everyone, for days I am trying to solve the same problem and I do not get it, after following the steps indicated in the instruction (https://auth0.com/blog/creating-your-first-real-world-angular-2-app-from-authentication-to-calling-an-api-and-everything-in-between/), I throw the following error:

SyntaxError: Unexpected token <
Evaluating http://localhost:3000/node_modules/angular2-jwt
Error loading http://localhost:3000/app/main.js

Someone found the solution? I would greatly appreciate your help!

@geminiyellow
Copy link

sorry i dont konw how to use SystemJS to load Auth0Lock, it alway module not found, is there anybody can help me?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants