Hi,
I use v10 with angular rc4 and router 3.0.0-beta.2. I do success to login (as seen on the auth0 dashboard) but the event 'authenticated' is never fired.
Here is my auth service
import { Injectable } from '@angular/core';
import { tokenNotExpired } from 'angular2-jwt';
// import { AngularFire } from 'angularfire2';
declare var Auth0Lock: any;
declare var Auth0: any;
declare var firebase: any;
@Injectable()
export class AuthService {
private lock = new Auth0Lock('aaaaa', 'bbbbb', { auth: { redirectUrl: 'http://localhost:3000', responseType: 'token'} });
private auth = new Auth0({ domain : 'ccccc', clientID: 'ddddd'});
private profile: Object;
constructor(/*private fire: AngularFire*/) {
this.profile = JSON.parse(localStorage.getItem('profile'));
this.lock.on('authenticated', (authResult): void => {
debugger;
localStorage.setItem('id_token', authResult.idToken);
this.lock.getProfile(authResult.idToken, (error:any, profile: any): void => {
if (error) {
throw error;
}
localStorage.setItem('profile', JSON.stringify(profile));
this.profile = profile;
});
let options: any = {
id_token: authResult.idToken,
api: 'firebase',
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
scope: 'openid name email',
target: 'aaaaa'
};
this.auth.getDelegationToken(options, (err, result): void => {
if (err) {
throw err;
}
// firebase.auth().signInWithCustomToken(result.id_token).catch((err) => {
// throw err;
// });
});
});
}
public getProfile = (): any => {
return this.profile;
}
public login = (): void => {
this.lock.show();
}
public authenticated = (): boolean => {
return tokenNotExpired();
}
public logout = (): void => {
localStorage.removeItem('id_token');
localStorage.removeItem('profile');
this.profile = null;
// firebase.auth().signOut();
}
}
I have a pretty basinc setup (project based on ng2-admin). I have a button that trigger the Auth.login() then i am redirected to http://localhost:3000 and i would then receive the event 'authenticated' but i dont.
It is surely good to notice that it is working in popup mode (tried email/pass, no external prover).
I am testing on win10 with chrome 51.0.2704.103.
Thank you
Can you tell us what version of Lock are you using?, if you are using auth0-angular or another wrapper?
If you can provide a sample project, it will be helpful
Hi,
I am using auth0-lock v10.0.1 (<script src="https://cdn.auth0.com/js/lock/10.0.1/lock.min.js"></script>) without any wrapper.
My auth service shown in my previous comment is showing how i call the lock widget.
I tried to reproduce with a blank project (using angular-cli) but i cannot reproduce it outside of my current project (based on ng-admin).
I think this might have something to do with the routing so here is my 2 routes files
../src/app/pages/pages.routes.ts
import {RouterConfig} from '@angular/router';
import {Home} from './home/home.component';
import {MonacoComponent} from './monaco/monaco.component';
import {CalendarPage} from './calendar/calendar.component';
import {RtcComponent} from './rtc/rtc.component';
import {Pages} from './pages.component';
export const PagesRoutes:RouterConfig = [
{
path: '',
component: Pages,
children: [
{
path: '',
component: Home,
data: {
menu: {
title: 'Home',
icon: 'ion-android-home',
selected: false,
expanded: false,
order: 0
}
}
},
{
path: 'monaco',
component: MonacoComponent,
data: {
menu: {
title: 'Monaco',
icon: 'ion-edit',
selected: false,
expanded: false,
order: 100
}
}
},
{
path: 'calendar',
component: CalendarPage,
data: {
menu: {
title: 'Calendar',
icon: 'ion-calendar',
selected: false,
expanded: false,
order: 100
}
}
},
{
path: 'rtc',
component: RtcComponent,
data: {
menu: {
title: 'RTC',
icon: 'ion-nuclear',
selected: false,
expanded: false,
order: 100
}
}
}
]
}
];
and ../src/app/app.routes.ts
import {provideRouter, RouterConfig} from '@angular/router';
import {PagesRoutes} from "./pages/pages.routes";
export const routes:RouterConfig = [
...PagesRoutes,
{
path: '**',
redirectTo: ''
},
];
export const APP_ROUTER_PROVIDERS = [
provideRouter(routes)
];
As said previously if i go to the auth0 console, i can see that the loging has been successful but the callback on 'authenticated' is never fired.
this.lock.on('authenticated', (authResult): void => {
debugger;
// never fired
});
Thank you
ps: if you wanna see the project here is the github https://github.com/cindoum/ngadmin
@cindoum have you tried with the latest [email protected]?
I think this might have something to do with the routing so here is my 2 routes files
we recently introduced a bugfix that might solve your issue: https://github.com/auth0/lock/blob/master/CHANGELOG.md#1022-2016-08-31
hi christian, ive updated the v10.2.2 but unfortunatly the my problem is not solved.
When i hit 'login with google' on the lock widget, i got redirected to
http://localhost:3000/#access_token=KVcbJf2EcrmE0tF8&id_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL2RvbWluaWNsYXBvaW50ZS5hdXRoMC5jb20vIiwic3ViIjoiZ29vZ2xlLW9hdXRoMnwxMDA2Njk3ODg0MTMyMTYwMzQ2NTYiLCJhdWQiOiJ1eVpQZnVwbTlYRU0yamREd2l6OXhHbXZEbmx5NXlkVSIsImV4cCI6MTQ3Mjg2NjI4OCwiaWF0IjoxNDcyODMwMjg4fQ.IgJg4zIETcpFaol-ihc9y8ihp3Bh3ngQ0q7Qv13y_Tk&token_type=Bearer&state=ccBz10ddhpmyIBNdKPCLOjTS
then the app just reload and the authenticated callback is not fired...
Might be good to say that i am using rc4 with router 3.0.0-beta.2.
I am trying to debug the issue. I found out where is the problem in lock.js
function parseHash(m, hash) {
var parsedHash = _web_api2.default.parseHash(l.id(m), hash);
l.emitHashParsedEvent(m, parsedHash);
var error = void 0,
result = void 0;
if (parsedHash) {
if (parsedHash.error) {
error = parsedHash;
} else if (!parsedHash.hasOwnProperty("error")) {
// NOTE: if the url hash contains the string "error"
// `parsedHash` will be the following object:
// {error: undefined, error_description: undefined}
// That is why we make the additional check for the error
// property to ensure we actually have a result.
result = parsedHash;
}
if (error) {
l.emitAuthorizationErrorEvent(m, error);
} else if (result) {
l.emitAuthenticatedEvent(m, result);
}
}
return !!(error || result);
}
I receive hash == null so parsedHash is == null so i dont get in the
if (parsedHash)
Where does this hash come from?
Thanks
@cindoum It might be possible that the uglify process you perform (if any) is wrongly handling the global.location.hash.
It will be better if you could provide a runnable sample (a simple github repo) with the steps to reproduce.
Yup i know but i just cant reproduce the issue outside of my project... (tried many times...)
I added a route to access_token,
path: 'access_token',
component: Home,
data: {
menu: {
hidden: true
}
}
with this new route, the 'authenticated' callback is now fired but the authResult is empty (no .idToken) like if lock couldnt parse the access token in the url...
any clue ?
Found out that this new route is removing the queryString so after le login (lock.show), i get redirected to /#access_token=xxxxx
then redirected to /#access_token (without qs)...
So when lock try to get the token it cant as the value are gone...
ps: why does lock fire emitEventAuthenticated if i am not really authenticated?
Thanks again
@cindoum
Having the same problem I solved it by removing
{provide: LocationStrategy, useClass: HashLocationStrategy},
from the providers array in app.module.ts
Yes this seem to be working. But i want to keep the hashLocationStrategy
I'm having similar problem. I'm also using HashLocationStrategy. For testing purposes, I tried not using it and lock seems to be working then. For me, it is impossible not to use HashLocationStrategy for production environment.
Versions:
@angular/router - 3.0.0-rc.1
auth0-lock - 10.2.2
Code:
...
lock = new Auth0Lock('', '');
constructor() {
this.lock.on('authenticated', (authResult) => {
console.log(authResult);
})
}
...
public login() {
this.lock.show();
}
...
Console outputs:
Object {accessToken: "", idToken: undefined, idTokenPayload: undefined, refreshToken: undefined, state: undefined}
Maybe this will help someone: https://github.com/auth0/auth0-angular/issues/118
It looks like the source of this issue is HashLocationStrategy - it can be simply reproduced by adding the HashLocationStrategy Provider to the login example.
For those who need to use HashLocationStrategy, one option is to add a helper method which listens to Router events and parses the hash with auth0.js.
import { Router } from '@angular/router';
import 'rxjs/add/operator/take';
@Injectable()
export class Auth {
lock = new Auth0Lock(AUTH0_CLIENT_ID, AUTH0_DOMAIN, {});
auth0 = new Auth0({clientID: AUTH0_CLIENT_ID, domain: AUTH0_DOMAIN});
constructor(private router: Router) {
this.lock.on('authenticated', authResult => {
localStorage.setItem('id_token', authResult.idToken);
});
this.lock.on('authorization_error', authResult => {
console.log(authResult);
});
this.handleRedirectWithHash();
}
private handleRedirectWithHash() {
this.router.events.take(1).subscribe(event => {
if (/access_token/.test(event.url) || /error/.test(event.url)) {
let authResult = this.auth0.parseHash(window.location.hash);
if (authResult && authResult.idToken) {
this.lock.emit('authenticated', authResult);
}
if (authResult && authResult.error) {
this.lock.emit('authorization_error', authResult);
}
}
});
}
...
Since Angular tries to parse the authentication hash before it is cleared, it can be picked up and checked in event.url.
I am having same problem using Vue.js 2.0 with vue-router.
The handleRedirectWithHash method work for me if i put it in my app.component.ts. Thank you, finally got it working.
Closing this one, since we need to rework the API of Lock to accommodate routers that can't be configured to prevent removing all the hash from the url.
This workaround https://github.com/auth0/lock/issues/527#issuecomment-257171395 is still valid and we'll reevaluate changing the API to support this scenario
Just FYI this is also the case when using auth0/lock with the upcoming react-router@v4. I had to use a similar workaround to what @chenkie posted above to parse the hash and retrieve the authResult payload.
I am trying to implement @chenkie 's solution but I am not sure how I can get the instance of the auth0 object to parse the hash. I am using Webpack. Which library should I import to get hold on the auth0 object?
@doorman02 in the latest release of Lock we added the method https://github.com/auth0/lock#resumeauthhash-callback to avoid using auth0.js for this case
Hi @hzalaz thanks for the info. So is it enough if I put the code inside the route change event handler and auth0 will continue with the process?
this.lock.resumeAuth(window.location.hash, (error, authResult) => {
if (error) {
alert("Could not parse hash");
}
console.log(authResult.accessToken);
})
;
Thanks @hzalaz problem finally solved :)
Thanks to @hzalaz & @doorman02 !
I'm working with the following release versions and @doorman02's code works.
<script src="https://cdn.auth0.com/js/auth0/8.0.0/auth0.min.js"></script>
<script src="https://cdn.auth0.com/js/lock/10.10.1/lock.min.js"></script>
<script src="js/vendor/angular-lock/dist/angular-lock.js"></script><!-- bower "angular-lock": "~2.0.0-beta.1" -->
<script src="js/vendor/angular-jwt/dist/angular-jwt.js"></script><!-- bower "angular-jwt": "~0.1.9" -->
FYI, my webapp is using Angular 1.6 with "angular-ui-router" (version "1.0.0-rc.1").
It successfully triggers the 'authenticated' event after the resumeAuth callback function is called AND the authResult parameter has non-null value.
Most helpful comment
For those who need to use
HashLocationStrategy, one option is to add a helper method which listens toRouterevents and parses the hash with auth0.js.Since Angular tries to parse the authentication hash before it is cleared, it can be picked up and checked in
event.url.