auth0 / auth0-spa-js Goto Github PK
View Code? Open in Web Editor NEWAuth0 authentication for Single Page Applications (SPA) with PKCE
License: MIT License
Auth0 authentication for Single Page Applications (SPA) with PKCE
License: MIT License
Hey 👋
After switching from auth0-js
to this package, I wanted to share a piece of feedback. But before I do, let me just say: This package is way simpler to use and understand. Great work!
One thing that is kind of awkward, however, is createAuth0Client
being async. And maybe that's because of how I've integrated it into my SPA, but I don't think it's that weird. Let me explain.
I call createAuth0Client
in a standalone file that I import where needed:
import createAuth0Client from '@auth0/auth0-spa-js'
export default createAuth0Client({
// My config...
})
When I import it, it looks something like this:
import auth0Client from './auth0_client'
async function main () {
const auth0 = await auth0Client
// Do something with `auth0`...
}
That just feels kind of weird to have to await for the client. I get that you're calling getTokenSilently
automatically if the user is authenticated – which is great – but since most (all?) of the other Auth0Client
functions return a Promise
already, couldn't you re-work it to make (and cache) that call in the constructor
, and then await
it in the other functions?
I realize that's a major version-type change. In the interim, maybe accept an argument to createAuth0Client
that skips the call to getTokenSilently
and returns the client right away? Or make it easy for developers to import Auth0Client
directly?
Hi!
I'm pretty new to this auth topic. I followed along the react tutorial. But when I click on loginwithredirect I get immediately this error 'Grant type 'authorization_code' not allowed for the client.'. I need to say that I'm using react with typescript.
I've copied the wrapper from @luisrudge in his answer here.
My config was working with the old js library though. Any suggestions what I did wrong?
Thanks
The lib was erroring on our project in IE 11 after updating to the spa lib from lock, and when testing with the demo application we get the same error. It looks like it's using some es6 syntax in the module (spread operator). I'm using differential loading, but it doesn't look like it effects node_modules. below are the errors from the demo app.
This is on IE 11.0.9600
Perhaps i'm doing something wrong in the configuration, but i can't find anything.
When using loginWithPopup:
let token;
try {
token = await auth0Client.getTokenWithPopup(params);
} catch (error) {
console.error(error);
}
An issue arrises that when an error occurs such as leaving the window open until it times out there is not a recourse to shut the popup window, possibly this should be a parameter with the getTokenWithPopup
where a parameter such as closePopupOnError
or otherwise would exist. We should also likely be able to control the timeouts associated with this rather than the hard coding to 30s inside of the util script.
This is a fairly large blocker for us but I am not certain how to handle this other than forking the current code and re-integrating it that way.
Not sure if that is a correct place. It seems that at some point the encoding of the user information is being lost. Not sure if that is library specific, but I've noticed that on my profile page while using auth0-samples/auth0-spa-js-angular-samples locally.
Here is GitHub SDK call:
curl https://api.github.com/users/peterblazejewicz
returning information:
"name": "Piotr Błażejewicz (Peter Blazejewicz)",
"company": ...
while the library keeps information as the:
{
"name": "Piotr B�ażejewicz (Peter Blazejewicz)",
"updated_at": ...
}
Thanks!
For me it"s hard to understand what's happening inside this stuff. So would be great for better examples. Everytime reloading/hot reload while developing, the app asks for login, that sucks alot. Even like described that it will automagically check with getTokenSilently is not happening. Don"t know why. But more detailed explanations would be great.
Hi,
I was reading the online documentation on how to use @auth0-spa-js with angular on the official website. So I installed it.
but have been getting this error:
ERROR in ./src/app/services/auth.service.ts
Module not found: Error: Can't resolve '@auth0/auth0-spa-js/dist/typings/Auth0Client' in
I'm not sure why this is happening? so I tried your sample project on GitHub. surprisingly enough it works.
I'm not sure what to do now.
My package.json content:
"dependencies": {},
"devDependencies": {
"@angular-devkit/schematics": "^8.1.1",
"@angular/animations": "^8.1.1",
"@angular/cdk": "^8.0.2",
"@angular/cli": "~8.0.2",
"@angular/common": "^8.1.1",
"@angular/compiler": "^8.1.1",
"@angular/core": "^8.1.1",
"@angular/flex-layout": "^8.0.0-beta.26",
"@angular/forms": "^8.1.1",
"@angular/material": "^8.0.2",
"@angular/platform-browser": "^8.1.1",
"@angular/platform-browser-dynamic": "^8.1.1",
"@angular/router": "^8.1.1",
"@auth0/auth0-spa-js": "^1.0.2",
"@ngx-progressbar/core": "^5.0.1",
"@ngx-progressbar/router": "^5.0.1",
"@ngx-translate/core": "^11.0.1",
"@ngx-translate/http-loader": "^4.0.0",
"angular-webstorage-service": "^1.0.2",
"bootstrap": "^3.4.1",
"chart.js": "^2.7.2",
"chartjs-plugin-zoom": "^0.7.2",
"classlist.js": "^1.1.20150312",
"core-js": "^3.1.4",
"font-awesome": "^4.7.0",
"hammerjs": "^2.0.8",
"mathjs": "^6.0.3",
"ng2-charts": "^2.3.0",
"ngx-clipboard": "^12.2.0",
"rxjs": "^6.2.1",
"rxjs-compat": "6.5.2",
"web-animations-js": "^2.3.1",
"zone.js": "^0.9.1",
"@angular-devkit/build-angular": "^0.801.1",
"@angular/compiler-cli": "^8.1.1",
"@angular/language-service": "^8.1.1",
"@types/jasmine": "^3.3.13",
"@types/jasminewd2": "~2.0.3",
"@types/node": "~12.6.2",
"codelyzer": "~5.1.0",
"jasmine-core": "~3.4.0",
"jasmine-spec-reporter": "~4.2.1",
"karma": "~4.1.0",
"karma-chrome-launcher": "~2.2.0",
"karma-coverage-istanbul-reporter": "^2.0.5",
"karma-jasmine": "~2.0.1",
"karma-jasmine-html-reporter": "^1.4.2",
"protractor": "^5.3.2",
"ts-node": "~8.3.0",
"tslint": "~5.18.0",
"typescript": "^3.4.5"
does somebody know about this issue?
please help
I noticed that most of the links to local files in this repo are broken on the https://auth0.github.io/auth0-spa-js/
site.
Also, the "Be sure to review the contributing guidelines" message I'm seeing on GH as I type this issue links to a 404 as well ( (I swear this was broken a moment ago!)https://github.com/auth0/auth0-spa-js/blob/master/CONTRIBUTING.md
).
Cheers
hi, Currently I have some problems with the transpilation of auth0-spa-js.production.js
Failed to compile.
Failed to minify the code from this file:
./node_modules/@auth0/auth0-spa-js/dist/auth0-spa-js.production.js:1:12440
Read more here: http://bit.ly/2tRViJ9
error Command failed with exit code 1.
I tried to use the build auth0-spa-js.production.legacy.js
, but it fails
import createAuth0Client from "@auth0/auth0-spa-js";
const auth0FromHook = await createAuth0Client(initOptions);
webpack alias:
'@auth0/auth0-spa-js': node_modules/@auth0/auth0-spa-js/dist/auth0-spa-js.production.legacy.js
looking for the function getTokenSilently in auth0-spa-js.production.js exists, but in auth0-spa-js.production.legacy.js it does not exist
"@auth0/auth0-spa-js": "^1.0.2",
The examples of this library in conjunction with roles and permissions (via Authorization Extension) utilise a rules file, which involves duplication of data which the extension already exists.
When using auth-js
there is a method called getPermissionScopes
which returns the same content as what the rules file contains.
Is there any plans to implement a similar method to get the information required, rather than duplication of the permissions and scopes please?
...or any additional information / best practises on how to implement this would be appreciated
He guys.
Is there a way to specify response type for an Auth0Client? As I can see response type is not part of Auth0ClientOptions.
I am trying to trigger the change password email which I could do using auth0-js
https://auth0.com/docs/libraries/auth0js/v9#password-reset-requests
Can we add a similar function to this library?
Every time page is refreshed, session is lost and user need to re-authenticate.
In index.ts, allow user to ignoreCache or not by passing option :
await auth0.getTokenSilently({
audience: options.audience,
scope: options.scope,
ignoreCache: options.ignoreCache // currently hard coded to true
});
If this suggestion makes sense, i can open a pull request for it, let me know !
Hi there,
I'm trying to integrate Auth0 into my SPA and I want to augment the react-auth0-spa sample code with better typing information (in this case using JSDoc in a plain JS project in VSCode) and it would be really helpful if Auth0Client
and Auth0ClientOptions
types were exported out of this package's typescript definition files (there might be other types that could be useful as well, but the two aforementioned ones are necessary to correctly type the interface of the react hook).
That way I could write something like
/** @typedef { import("@auth0/auth0-spa-js").Auth0Client } */
/** @type { [Auth0Client, (Auth0Client) => void ] } */
const [auth0Client, setAuth0] = useState();
See the Typescript JSDoc support documentation for details on the type syntax.
Hi, how would the React wrapper work in combination with @apollo/hooks?
At some point in my application, I would like to add an additional header with my access token if the user decided to log in. Some graphql queries should be available when the user isn't logged in.
So I have a scenario where I want to add the header only at a later point.
Good work so far on this package!
I'm looking at how to authenticate an account using this package without affecting the currently logged in account such that I can trigger the accounts to be linked.
Example:
I have account A
logged in using email/password and they want to click a button to authenticate a social network account B
but does not want the app to be logged into that social network account.
Am I correct thinking that:
import createAuth0Client from '@auth/auth0-spa-js';
const accountAAuth0 = await createAuth0Client({ domain: 'xxx', client_id: 'yyy' });
await accountAAuth0.loginWithPopup();
const accountAUser = await accountAAuth0.getUser();
const accountBAuth0 = await createAuth0Client({ domain: 'xxx', client_id: 'yyy' });
await accountBAuth0.loginWithPopup();
const accountBUser = await accountBAuth0.getUser();
const accountAUserCopy = await accountAAuth0.getUser();
const worked = (
accountAUserCopy.sub === accountAUser.sub
&& accountAUserCopy.sub !== accountBUser.sub
);
Is there a way to do this using redirect logins as well?
Hi there,
I've experimenting with the new library and it looks like the default value of { }
is not set for the RedirectLoginOptions
in the loginWithRedirect
method.
When I call the method like this:
client.loginWithRedirect();
I get the error:
TypeError: r is undefined
But if I call it with an empty Object, everything works fine:
client.loginWithRedirect({});
I'm not familiar with TypeScript, but when I look at the code, a default value is set:
https://github.com/auth0/auth0-spa-js/blob/master/src/Auth0Client.ts#L194
However, when I check the compiled file auth0-spa-js.production.js:834
, it's missing:
loginWithRedirect(r) { // no default value is set
return t(this, void 0, void 0, function* () {
const t = r.redirect_uri,
o = r.appState,
n = e(r, ["redirect_uri", "appState"]),
i = A(k()),
a = k(),
s = k(),
c = yield N(s),
l = F(c),
d = this._getParams(n, i, a, l, t),
u = this._authorizeUrl(d);
this.transactionManager.create(i, {
nonce: a,
code_verifier: s,
appState: o,
scope: d.scope,
audience: d.audience || "default"
}), window.location.assign(u);
});
}
Any idea why this is happening? I'm happy to send a PR with a fix if needed.
On a side note, the link to the Auth0's contribution guidelines in CONTRIBUTING.md
seems to be broken. It links to GENERAL-CONTRIBUTING.md
, but it looks like that file is not present in this repo:
https://github.com/auth0/auth0-spa-js/blob/master/GENERAL-CONTRIBUTING.md
I can't find it now, but the original doc/guide I was using (from Auth0) said to use node-jsonwebtoken
to verify the access token in the auth header. But the token isn't JWT, so I'm not really sure how to verify a user when they hit the API or how to associate that user with a DB record.
I got the login working on the fronted, but yea, I'm stuck on where to go from there. Sorry if dumb question, just a bit confused.
Getting the same issue. Trying to login using gmail. Login is succesful but on Approving access to the application, the page redirects to http://localhost:3000/?code=YpqazoJ6B_RazjFx&state=Mm05b19LSlZSekxaTGpnZGR1aHhBNnF%2BSkhiczZneHI3dm91anI3NEF5RA%3D%3D and gives the error in console. Check attached screeenshot
Kindly help resolve.
So i tried to make things work with the described example from the react wrapper, also managed to make things work. The problem we have right now is when reloading the app the isAuthenticated is always undefined. We wrapped the Code inside a AppContext wich provides these things for other components and than loads an AuthenticatedApp or UnauthenticatedApp. When flushing the cache and reload the whole Application everything works, but after hitting reload again the isAuthenticated is always undefined. Maybe someone is having the similiar issues.
Code for App:
const loadAuthenticatedApp = () => import('./authenticated-app');
const AuthenticatedApp = React.lazy(loadAuthenticatedApp);
const UnauthenticatedApp = React.lazy(() => import('./unauthenticated-app'));
interface IPrivateApp {
path?: string;
}
const App: React.FC<IPrivateApp> = ({ path, ...rest }) => {
const { isAuthenticated, loginWithRedirect } = useAuth0();
React.useEffect(() => {
const fn = async () => {
console.log(`AUTH STATUS`, isAuthenticated);
if (isAuthenticated === false) {
await loginWithRedirect({
appState: { targetUrl: path },
redirect_uri: '',
});
}
};
fn();
}, [isAuthenticated, loginWithRedirect, path]);
// React.useEffect(() => {
// loadAuthenticatedApp();
// }, []);
return (
<Suspense fallback={<CircularProgress />}>
{isAuthenticated ? <AuthenticatedApp {...rest} /> : <UnauthenticatedApp />}
</Suspense>
);
};
export default App;
And Code for the Provider:
import React, { useState, useEffect, useContext, useLayoutEffect } from 'react';
import createAuth0Client from '@auth0/auth0-spa-js';
import Auth0Client from '@auth0/auth0-spa-js/dist/typings/Auth0Client';
interface Auth0Context {
isAuthenticated: boolean;
user: any;
loading: boolean;
popupOpen: boolean;
loginWithPopup(options: PopupLoginOptions): Promise<void>;
handleRedirectCallback(): Promise<RedirectLoginResult>;
getIdTokenClaims(o?: getIdTokenClaimsOptions): Promise<IdToken>;
loginWithRedirect(o: RedirectLoginOptions): Promise<void>;
getTokenSilently(o?: GetTokenSilentlyOptions): Promise<string | undefined>;
getTokenWithPopup(o?: GetTokenWithPopupOptions): Promise<string | undefined>;
logout(o?: LogoutOptions): void;
}
interface Auth0ProviderOptions {
children: React.ReactElement;
onRedirectCallback?(result: RedirectLoginResult): void;
}
const DEFAULT_REDIRECT_CALLBACK = () => window.history.replaceState({}, document.title, window.location.pathname);
export const Auth0Context = React.createContext<Auth0Context | null>(null);
export const useAuth0 = () => useContext(Auth0Context)!;
export const Auth0Provider = ({
children,
onRedirectCallback = DEFAULT_REDIRECT_CALLBACK,
...initOptions
}: Auth0ProviderOptions & Auth0ClientOptions) => {
const [isAuthenticated, setIsAuthenticated] = useState();
const [user, setUser] = useState();
const [auth0Client, setAuth0] = useState<Auth0Client>();
const [loading, setLoading] = useState(true);
const [popupOpen, setPopupOpen] = useState(false);
useEffect(() => {
const initAuth0 = async () => {
const auth0FromHook = await createAuth0Client(initOptions);
console.log(`SET AUTH0`);
setAuth0(auth0FromHook);
if (window.location.search.includes('?code=')) {
const { appState } = await auth0FromHook.handleRedirectCallback();
onRedirectCallback(appState);
}
const isAuthenticated = await auth0FromHook.isAuthenticated();
setIsAuthenticated(isAuthenticated);
if (isAuthenticated) {
const user = await auth0FromHook.getUser();
setUser(user);
}
setLoading(false);
};
initAuth0();
// eslint-disable-next-line
}, []);
const loginWithPopup = async (o: PopupLoginOptions) => {
setPopupOpen(true);
try {
// non null assertion operator - expression to tell the compiler
// that this could not be null or undefined
// READ MORE: https://github.com/Microsoft/TypeScript/wiki/What's-new-in-TypeScript#non-null-assertion-operator
await auth0Client!.loginWithPopup(o);
} catch (error) {
console.error(error);
} finally {
setPopupOpen(false);
}
const user = await auth0Client!.getUser();
setUser(user);
setIsAuthenticated(true);
};
const handleRedirectCallback = async () => {
setLoading(true);
const result = await auth0Client!.handleRedirectCallback();
const user = await auth0Client!.getUser();
setLoading(false);
setIsAuthenticated(true);
setUser(user);
return result;
};
return (
<Auth0Context.Provider
value={{
isAuthenticated,
user,
loading,
popupOpen,
loginWithPopup,
handleRedirectCallback,
getIdTokenClaims: (o: getIdTokenClaimsOptions | undefined) => auth0Client!.getIdTokenClaims(o),
loginWithRedirect: (o: RedirectLoginOptions) => auth0Client!.loginWithRedirect(o),
getTokenSilently: (o: GetTokenSilentlyOptions | undefined) => auth0Client!.getTokenSilently(o),
getTokenWithPopup: (o: GetTokenWithPopupOptions | undefined) => auth0Client!.getTokenWithPopup(o),
logout: (o: LogoutOptions | undefined) => auth0Client!.logout(o),
}}
>
{children}
</Auth0Context.Provider>
);
};
And the index.tsx:
render(
<ApolloProvider client={ApolloClient}>
<Router history={history}>
<AppProvider>
<App />
</AppProvider>
</Router>
</ApolloProvider>,
document.getElementById('root') as HTMLElement,
);
Hi,
I was questioning myself about the use of 'auth0.is.authenticated' cookie as it has been confusing to me (I searched for an answer on other issues but could not find one, sorry if I missed it).
What seem strange to me is that, when creating an auth0 client, presence of this cookie is checked before we try to authenticate silently.
Here is the line https://github.com/auth0/auth0-spa-js/blob/master/src/index.ts#L11
What exactly is the purpose of such check ? (and thus the purpose of such cookie).
My use case is: I have an (quite old) angularjs app which directly uses auth0-js and a new react app which uses auth0-spa-js. If I login on my angularjs app, then navigate to my react app, since the 'auth0.is.authenticated' cookie is not present, my react app won't try silent authentication and I won't be logged in.
Though I could myself trigger a silent auth when my auth0 client finished loading, I would expect the lib to always do it whatever the cookie is because there might be an auth0 session existing for me.
Please enlighten me on this, did I miss something ?
Cheers
We have an environment deployed on Azure which is used for test automation. Currently, as it is limited by ip address, we don't have https set up on this environment.
When we do a build of our code with this library incorporated, I get and error when I hit the login button, which is in turn calling loginWithRedirect
. We use a slightly modified version of the Auth0 React wrapper from the examples, but is verbatim of the example for the loginWithRedirect
function.
The error I get (which could be clearer or mitigated against possibly) is:
Uncaught (in promise) TypeError: Cannot read property 'digest' of undefined
at q (auth0-spa-js.production.js:570)
at t.<anonymous> (auth0-spa-js.production.js:1052)
at u (runtime.js:45)
at Generator._invoke (runtime.js:264)
at Generator.e.<computed> [as next] (runtime.js:98)
at auth0-spa-js.production.js:66
at new Promise (<anonymous>)
at n (auth0-spa-js.production.js:43)
at t.value (auth0-spa-js.production.js:1037)
at loginWithRedirect (Auth.tsx:151)
which points to line 570 of auth0-spa-js.production.js, which on mine reads:
569 N = function N(e) {
570 return window.crypto.subtle.digest({
571 name: "SHA-256"
572 }, new TextEncoder().encode(e));
If this library is not intended to be ran in http in a prod environment, then I think that needs to be made clear. If it should "cope", then some checking and handling needs to be done here too.
On the old auth0-js tutorial, you could renew the token until the user session expires. How would one implement it in the auth0-spa-js?
Hi,
window.crypto only works in secure origin w3c/webcrypto#28
Line 92 in b9ae10f
Is the behavior expected?
is it possible to use crypto-js?
It would be nice if handleRedirectCallback
would extract error responses to the callback. I'm envisioning it throwing an error with with the error
and error_description
params for instance.
Hi,
Would be great to be able to access RBAC (Authorization Core) permissions in the SPA so as to be able to extend the PrivateRoute component to restrict routes based on permission.
Can see how to get the permissions included in the access token for my API but unsure how to get access to them in the SPA.
Many thanks, Ed
Hi, I'm trying to use the auth0 library in my project but I'm getting an error:
ts_scripts.js?v=1563805379409:34261 ERROR Error: Uncaught (in promise): TypeError: auth0_spa_js_1.default is not a function
TypeError: auth0_spa_js_1.default is not a function
I've seen some similiar issues, #60, #45, but their setups are a bit different and I've tried the suggested tsconfig fixes and I couldn't get them to work.
My project uses a setup similar to the angular-bazel-example, so I've created a repro of the problem using it. Steps are below.
cd /tmp
git clone https://github.com/Dig-Doug/angular-bazel-example.git
cd angular-bazel-example
git checkout 8fa48dc1b977c435178aa5bfc1f9d601ed15f5b7
yarn install
npx bazel run //src:devserver
# It should say "Server listening on XXX"
The auth service from the example is in src/app/auth/
and I've tried to use the service in src/app.component.ts
.
When you connect to the local server, the page will load and lots of messages will be printed to the console. Make sure you scroll to the top, the error message is there.
I think the problem has something to do with how the auth0
library is being exported or imported. Looking at the generated code, auth.service.js
(note JS), it tries to access the library with:
this.auth0Client = yield auth0_spa_js_1.default(this.config);
In my main project I use lots of other 3rd party libraries, e.g. immutable
, three
, without issue so it's not an issue with loading libraries in general.
Please let me know if you need any more info.
Thanks!
I have created the SPA and I've created an API. When I use the example and call the handleRedirect
function, I see the call go out to the /token
endpoint which does return an id_token
. That said, I don't see any way to actually get that token and save it to local storage.
I copied it and used it directly in Postman to call an API, and I'm getting Expected {different audience}
and auth does not work. What am I missing here?
Also how does the API know that the SPA's client I created is authorized to access it? Do I need a service to use the secret key to generate a token or something?
Hey 👋
I have a Vue CLI app that I've adding this package to via npm. I have it all working in modern browsers, but IE 11 throws a number of errors related to missing features (i.e., String.prototype.startsWith
).
I could be totally off here, but it looks like dist/auth0-spa-js.production.js
is built to be ES5 compatible, and work in IE 11?
If not, my follow-up question: What are the polyfills this package needs for IE 11?
Vue CLI recommends either explicitly including the polyfills needed (which I've done with other dependencies), or just including all polyfills for your target browsers. I'd rather not include all polyfills if possible.
Hello, been following the new documentation for Angular and i am finding that when i get to the this.auth0Client = await createAuth0Client(this.config);
it awaits for near exactly 60 seconds, which is an issue if the user clicks the login button before that and gets the following error in the console.
Error: "Uncaught (in promise): TypeError: this.auth0Client is undefined
My code is exactly the same as what's provided in the documentation.
Any ideas?
Seems like there is nos straight forward way of taking a user to the sign up page.
Maybe loginWithRedirect could take an option to take the user directly to the sign up page.
Hi Guys,
Using this new library I am getting this error all the time, not sure why:
core.js:15724 ERROR TypeError: auth0_spa_js_1.default is not a function
at auth0.service.ts:32
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:423)
at Object.onInvokeTask (core.js:17290)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:422)
at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:195)
at push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask (zone.js:498)
at ZoneTask.invoke (zone.js:487)
at timer (zone.js:2281)
And here is my code:
private auth0Client: Auth0Client;
// Auth0 application configuration responseType: 'token id_token',
config: Auth0ClientOptions = {
domain: 'my.custom.domain',
client_id: 'MY_CLIENT_ID',
redirect_uri: `${ window.location.origin }/callback`,
scope: 'openid profile email',
audience: 'https://myapi.auth0.com/api/v2/',
display: 'popup',
prompt: 'login'
};
constructor() {
setTimeout( () => {
from(createAuth0Client(this.config)).subscribe( (client: Auth0Client) => {
this.auth0Client = client;
console.log(`createAuth0Client: ${ JSON.stringify(client) }`);
this.authClientSubject.next(this.auth0Client);
});
}, 1000);
}
I've tried using setTimeout and without, always the same, createAuth0Client is undefined :(
Any idea?
Thanks.
I'm trying to get an access token to be able to change some user metadata. This is what I have so far:
async getAuth0Client(): Promise<Auth0Client> {
if (!this.auth0Client) {
this.auth0Client = await createAuth0Client(this.config);
// Provide the current value of isAuthenticated
this.isAuthenticated.next(await this.auth0Client.isAuthenticated());
// Whenever isAuthenticated changes, provide the current value of `getUser`
this.isAuthenticated.subscribe(async isAuthenticated => {
if (isAuthenticated) {
this.profile.next(await this.auth0Client.getUser());
this.backendToken.next(await this.auth0Client.getTokenWithPopup());
this.managementToken.next(await this.auth0Client.getTokenWithPopup({
audience: 'https://{project}.{region}.auth0.com/api/v2/',
scope: 'update:users update:users_app_metadata'
}));
return;
}
this.profile.next(null);
});
}
return this.auth0Client;
}
However, my managementToken
only contains the usual scopes openid email profile
, not the ones I explicitly stated.
The profile
contains the user metadata I set via the auth0-website, but I cannot update it via this.http.patch(
http://{project}.{region}.auth0.com/api/v2/users/${this.profile.sub}, this.profile)
.
I also tried to create a second auth0Client
for the management api, but this mixes up the state when authenticating. Any idea what I'm doing wrong?
I followed QuickStart to integrate this into my NextJs application. But got this error message:
ReferenceError: window is not defined
In my index.js:
import React, { Component } from "react";
import Home from './home'
import { Auth0Provider } from "../services/auth0";
import config from "../services/auth_config.json";
// A function that routes the user to the right place
// after login
const onRedirectCallback = appState => {
window.history.replaceState(
{},
document.title,
appState && appState.targetUrl
? appState.targetUrl
: window.location.pathname
);
};
class Index extends Component {
render() {
return (
<Auth0Provider
domain={config.domain}
client_id={config.clientId}
redirect_uri={window.location.origin}
onRedirectCallback={onRedirectCallback}
>
<Home/>
</Auth0Provider>
);
}
}
export default Index;
Any idea? Thanks.
Hi!
I'm having an error in the console when creating the Auth0 client using createAuth0Client()
.
The error is the following:
> ERROR TypeError: Cannot read property 'close' of undefined
at o (auth0-spa-js.production.js:formatted:1)
at ZoneDelegate.invokeTask (zone-evergreen.js:391)
at Object.onInvokeTask (auth0-spa-js.production.js:formatted:1)
at ZoneDelegate.invokeTask (zone-evergreen.js:390)
at Zone.runTask (zone-evergreen.js:168)
at ZoneTask.invokeTask [as invoke] (zone-evergreen.js:465)
at invokeTask (zone-evergreen.js:1603)
at globalZoneAwareCallback (zone-evergreen.js:1640)
On the beautyfied production code, the error points to this line:
o = function(i) {
// Below is the culprit, apparently, 'i.source' is undefined
i.origin == m && i.data && "authorization_response" === i.data.type && (i.source.close(),
i.data.response.error ? t(i.data.response) : e(i.data.response),
clearTimeout(n),
window.removeEventListener("message", o, !1),
window.document.body.removeChild(r))
};
And the code that's calling the createAuth0Client()
function is this one (pretty much the exact same as the Angular Login Tutorial):
// This is a method of my AuthService
async getAuth0Client(): Promise<Auth0Client> {
if (!this.auth0Client) {
console.log("AuthService - generating new Auth0Client");
this.auth0Client = await createAuth0Client(environment.auth0);
console.log("AuthService - new Auth0Client", this.auth0Client);
// Provide the current value of isAuthenticated
this.isAuthenticated.next(await this.auth0Client.isAuthenticated());
// Whenever isAuthenticated changes, provide the current value of `getUser`
this.isAuthenticated
.subscribe(async isAuthenticated => await this.updateUserProfile(isAuthenticated));
}
return this.auth0Client;
}
Note that this error does not prevent the client to be effectively created and functionning. But it's still an unwanted error 😄
Also, some other people seem to have the same kind of issue, see this thread in the Auth0 Community Forums
Hello! I was using the old quickstart for auth0-js
until today it seems the docs have swapped over to the new auth0-spa-js
ones -- no problem.
I was wondering if you had any plans to release an example for the spa module in typescript.
Thanks!
The error is
Unhandled Rejection (TypeError): Cannot read property 'getTokenSilently' of undefined
Works fine after the page is loaded.
Is this intended?
If I'd like to put the token in my redux storage, I'd have to use componentDidMount which is getting depricated by the React team.
What's the difference between auth0-spa-js
and auth0-js
?
I was integrating using auth0-js
and recently looked at React samples to see that it was completely different from before and now uses auth0-spa-js
instead of auth0-js
.
Should I switch over to auth0-spa-js
from auth0-js
?
Hey guys,
I've been switching the use the new auth0 login with hooks, when I try to do something very similar to the example, I keep encountering the following error:
TypeError: Cannot read property 'loginWithRedirect' of undefined
It appears that auth0Client is never getting set, so I'm never able to call loginWithRedirect on it. My credentials appear to be correct, and I've been able to login previously with them, so I'm wondering why that is.
My code:
function Home(props) {
const [value, setValue] = useState("");
const { isAuthenticated, loginWithRedirect, logout } = useAuth0();
const { sessionSubmitted, setSessionSubmitted } = useState(false);
function handleChange(event) {
setValue(event.target.value);
}
function handleSessionSubmit() {
console.log("we are handling session submit");
console.log(value);
props.history.push({
pathname: "/session",
search:
"?" +
new URLSearchParams({
sessionId: value
}).toString(),
state: {
sessionId: value
}
});
}
return (
<div class="Home">
{" "}
<div className="bar">
<AppBar
position="static"
style={{ background: "transparent", boxShadow: "none" }}
>
<Toolbar>
<div className="title">
<Typography variant="title"> Frindle </Typography>{" "}
</div>{" "}
<Button onClick={() => loginWithRedirect({})}>
{" "}
Sign Up{" "}
</Button>{" "}
<Button onClick={() => loginWithRedirect({})}>
{" "}
Login{" "}
</Button>{" "}
</Toolbar>{" "}
</AppBar>{" "}
</div>{" "}
<div className="sessionForm">
<form onSubmit={handleSessionSubmit}>
<div className="text">
<TextField
name="session"
label="Session ID"
value={value}
onChange={handleChange}
margin="normal"
variant="outlined"
/>
</div>{" "}
<div className="button">
<Button
type="submit"
color="primary"
variant="outlined"
className="button"
>
Submit{" "}
</Button>{" "}
</div>{" "}
</form>{" "}
</div>{" "}
</div>
);
}
export default withRouter(Home);
Hi,
I've just downloaded the example app from the auth0 page and it seems it's not working. After looking at the URL the login process generates I've noticed this:
error_description=Cannot read property 'persons' of undefined
What am I missing?
I am getting the following error in the download sample that you guys have provided for the react quick start of auth0
Uncaught (in promise) TypeError: Cannot read property 'split' of undefined
at auth0-spa-js.production.js:685
When the promise resolves and returns me my Auth0Client I don't seem to have any methods:
I'm following the example from the docs using promises (not with async).
Hi auth0 team.
I tried to use the angular http interceptor to set headers in the request.
But when I added the httpInterceptor service, auth0-spa package not working.
the function isAuthenticated()
is not working, seem like the request url to the auth0 is replace (but I did nothing with the url in the interceptor).
Here is the request URL:
https://authorize/?client_id=&audience=&scope=openid%20profile%20email&redirect_uri=http%3A%2F%2Flocalhost%3A4200%2Fauth0%2Fcallback&response_type=code&response_mode=web_message&state=WXNwOE1jUGVrMDg3NjU2dVBPSzc1aFZIRHJjfjduWnRSbmF5eTk5UjIwZw%3D%3D&nonce=QJ94AvDv.tski5fNTffzNy35Zyx7AZHZkHg93XRb.Al&code_challenge=XW6i-5f14LC0KYpyBVQY28uLJ0JJLJ34RT2Z9iCuvzI&code_challenge_method=S256&prompt=none&auth0Client=eyJuYW1lIjoiYXV0aDAtc3BhLWpzIiwidmVyc2lvbiI6IjEuMC4xIn0%3D
I did notice that the request url is being replace and now it only https://
.
If I remove the http interceptor, the request url will be https://my-domain.com/authorize/....
and it work perfectly.
The interceptor service:
export class HttpInterceptorService implements HttpInterceptor {
token: string;
constructor(private _router: Router,
private _dialog: MatDialog,
private _auth0Service: AuthService,
private _messageService: MessageService) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this._messageService.startFetchingData();
console.log(request);
console.log(`start fetching data`);
this._auth0Service.token.subscribe(_token => this.token = _token );
request = request.clone({
setHeaders: {
Authorization: 'Bearer ' + this.token
}
});
return next.handle(request).pipe(
tap((event: HttpEvent<any>) => {
// catch http response
if (event instanceof HttpResponse) {
this._messageService.finishFetchingData();
}
console.log(`finish fetching data`);
return event;
}),
catchError((httpErrorResponse: HttpErrorResponse) => {
this._messageService.finishFetchingData();
switch (httpErrorResponse.status) {
case 500: {
this._dialog.open( Error500DialogComponent, {
autoFocus: false
});
break;
}
case 401: {
this._router.navigate(['/public/signin']);
break;
}
}
return throwError(httpErrorResponse);
})
);
}
}
Hello,
I'm using the same example of the auth0-spa-js quickstart with typescript and it fails all the time.
this is the code:
import * as React from "react";
import createAuth0Client from '@auth0/auth0-spa-js'
// already tried also
// import * as createAuth0Client from '@auth0/auth0-spa-js'
import {canUseDom} from "../domUtils";
type ProviderProps = Auth0ClientOptions & {
onRedirectCallback: any,
ssrUser: any
}
type ContextValueType = {
isAuthenticated?: boolean,
user?: any,
loading?: boolean,
popupOpen?: boolean,
loginWithPopup?: (params: any) => void,
handleRedirectCallback?: () => void,
getIdTokenClaims?: (...p: any) => any,
loginWithRedirect?: (...p: any) => any,
getTokenSilently?: (...p: any) => any,
getTokenWithPopup?: (...p: any) => any,
logout?: (...p: any) => any
}
const DEFAULT_REDIRECT_CALLBACK = (appState: any) =>
// @ts-ignore
canUseDom() ? window.history.replaceState({}, document.title, window.location.pathname) : null;
export const Auth0Context = React.createContext<ContextValueType>({});
export const useAuth0 = () => React.useContext(Auth0Context);
export const Auth0Provider: React.FC<ProviderProps> = ({
children,
ssrUser,
onRedirectCallback = DEFAULT_REDIRECT_CALLBACK,
...initOptions
}) => {
const [isAuthenticated, setIsAuthenticated] = React.useState();
const [user, setUser] = React.useState();
const [auth0Client, setAuth0] = React.useState();
const [loading, setLoading] = React.useState(true);
const [popupOpen, setPopupOpen] = React.useState(false);
if(ssrUser){
setUser(ssrUser)
setIsAuthenticated(!!ssrUser)
}
React.useEffect(() => {
const initAuth0 = async () => {
// **it breaks here!**
const auth0FromHook = await createAuth0Client(initOptions);
setAuth0(auth0FromHook);
if (canUseDom() && window.location.search.includes("code=")) {
const {appState} = await auth0FromHook.handleRedirectCallback();
onRedirectCallback(appState);
}
const isAuthenticated = await auth0FromHook.isAuthenticated();
setIsAuthenticated(isAuthenticated);
if (isAuthenticated) {
const user = await auth0FromHook.getUser();
setUser(user);
}
setLoading(false);
};
initAuth0();
// eslint-disable-next-line
}, []);
const loginWithPopup = async (params = {}) => {
setPopupOpen(true);
try {
await auth0Client.loginWithPopup(params);
} catch (error) {
console.error(error);
} finally {
setPopupOpen(false);
}
const user = await auth0Client.getUser();
setUser(user);
setIsAuthenticated(true);
};
const handleRedirectCallback = async () => {
setLoading(true);
await auth0Client.handleRedirectCallback();
const user = await auth0Client.getUser();
setLoading(false);
setIsAuthenticated(true);
setUser(user);
};
return (
<Auth0Context.Provider
value={{
isAuthenticated,
user,
loading,
popupOpen,
loginWithPopup,
handleRedirectCallback,
getIdTokenClaims: (...p: any) => auth0Client.getIdTokenClaims(...p),
loginWithRedirect: (...p: any) => auth0Client.loginWithRedirect(...p),
getTokenSilently: (...p: any) => auth0Client.getTokenSilently(...p),
getTokenWithPopup: (...p: any) => auth0Client.getTokenWithPopup(...p),
logout: (...p: any) => auth0Client.logout(...p)
}}
>
{children}
</Auth0Context.Provider>
);
};
When I'm trying to use this component then I got the error :
Unhandled Rejection (TypeError): auth0_spa_js_1.default is not a function
I've been dealing with this issue for days and no solution yet. I'm kinda in a hurry right now. Have anyone of you experienced this?
kind regards,
Ibrael
Using the old SDK, when I called my server API with my access token, on the server I would also have a user object with nickname
, email
, and picture
. After updating to this library, that data is no longer available. My server code relies on this. Is there something wrong with my configuration? A bug in this library? A breaking change that no longer makes this info available?
Any assistance would be great.
I've followed the SPA quick start guide and got it working. My problem now is that that guide kinda forces you to manage authentication through your component tree by having the Auth0Context around your entire app. Is there any problem in exposing the auth0Client globally to the app? My issue is regarding API calls. Following the guide, I realized that I need to call getTokenSilently but the way the guide puts it this is only available inside component functions. If I want to have an API module the deals with API calls only how can I access the auth0Client? Am I thinking this wrong?
Thank you!
Creating an optimized production build...
Failed to compile.
Failed to minify the code from this file:
./node_modules/@auth0/auth0-spa-js/dist/auth0-spa-js.production.js:1:12440
I'm getting the above error when attempting to run npm build
on my create-react-app
created application.
I'm running:
"@auth0/auth0-spa-js": "^1.0.1",
"react-scripts": "^2.1.3",
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.