This seems to be a recent change in the API, so not sure where to fine info about it. Could you please point me in the right direction.
Regarding this commit https://github.com/auth0/auth0.js/commit/cf57a6ae6c962e5bd6a162e1d2774cf7eec06a56
I am a bit confused as we need to send access token to get user's profile. I will have to store two tokens in my localStorage. What is the best practice for doing this?
What happens when my idToken expires and the user comes back to my application. I see that my accessToken doesn't expire the same time and I still get user's profile by calling getUserInfo. But all my idToken related operations will be unauthorised.
I noticed the same. I am using the auth0.getProfile(...) method (which isn't deprecated), which in turns logs deprecation message when used, which is related to the same commit as you mentioned.
For now I'll just revert to 7.3.0. getUserInfo() feels a bit rough around the edges as it is not even documented on the README yet (unlike getProfile()). Maybe it will be added there soon, to show how it should/could be used.
@salmanm we are in the process of introducing the API Authorization feature. This is an important shift with regards of the usage of id_token and access_token. This required a refactoring of our authentication pipeline and one of the consequences is that the access_token takes more relevance than the id_token. As a consequence also, the use of the endpoint /tokeninfo will be deprecated in favor of the use of /userinfo with the access_token instead.
My recommendation would be to use the new pipeline. You can enable it by going to Account Settings => OAuth 2.0 API Authorization. These are some of the things that you will need to change:
audience parameter in Lock to specify what API you need access to (make sure to create that API in the dashboard)getUserInfo, id_token is not needed.silentAuthentication to refresh the access_token if it expiredFor the record, id_token will continue to work fine, but it's not what we will recommend going forward for talking to APIs. Specially, in light with the introduction to third party clients consuming your API. We will release a proper migration guide soon that will explain this in more detail, but wanted to give you a preview, since it created this confusion.
Also OAuth 2.0 API Authorization is only available in the US for now
Thanks for the information! I am using id_token and refresh_token only currently, so I better wait for the migration guide to getter a better idea of how to use it in our apps :)
Thanks @hzalaz for the info. Could you please clarify the following a bit more!
Store the access_token and call getUserInfo, id_token is not needed
Does that mean I no longer have to store idToken in localStorage? If so, how do I transfer identity claim to my API? I used to send jwt (idToken) to the server in each request and authenticate the same on the server. How would this flow change with the new accessToken precedence?
@salmanm depends what you use the identity claim for, if you use it to authorize the user to call your api, you need to use the access_token instead (after enabling and configuring API Authorization) since its meant for authorizing access to your API. If you need to know the identity of the user in the backend, sending the access_token and calling /userinfo in your server is the way to go.
Feel free to contact us in https://support.auth0.com for further assistance.
What is the significance of jwt then? Will it not be used anymore?
The problem with accessToken is that I have to hit Auth0 to check its validity. I love the idea of jwt where at least you can extract certain information out of it and hit Auth0 API only when needed.
i also have a concern about this, we will use it in a production application and there is no way to disable the warning even if it's not deprecated yet..
@salmanm to check if the token is valid you always need to call your API from your SPA, either getProfile (calls /tokeninfo endpoint) or the new and non-deprecated getUserInfo (calls /userinfo). A jwt token is only validated by checking it's signature and for that you need to know the secret used to sign the token, which won't be in your SPA for security reasons, that's why a call to auth0 is needed.
If you want to avoid calling Auth0 to get user info, you could just use decodeJwt method to decode the id_token and get the info stored in it.
In the current version of auth0.js (v7), getProfile avoids making the call by checking the content of the decode id_token but you can easily replicate that with decodeJwt.
@chocmah we have available both in lock and in auth0.js a method to call /userinfo with the access_token returned by Auth0 if you want to avoid the warning
Sorry my question was that if I can use access_token for getting user's profile (on frontend as well as in my API) when exactly would I use jwt?
@salmanm jwt is just the token format, the access_token itself might be a son web token 馃槃 .
The id_token, since it's a jwt, can be decoded to extract user information you requested during auth, via scope parameter, and that way you avoid the remote API call.
Also you can ignore the id_token altogether and always request the user information via the API Call.
@hzalaz Is the migration guide available yet? I'm outside US and I'm getting deprecation notice for my getProfile(id_token) call. I am also storing my id_token in localStorage (and not the access_token). I'm sending the id_token to my ASP.NET WebApi backend and decoding it using jwtbearer.
Is there a timeline for how long the getProfile call will work, when the migration guide is out and when the new pipeline is ready to use for production (including outside US)?
@mikeesouth is not, we are slowly making p2 available in other regions and once it's available we will publish a migration guide. For the time being since you are relying on that method you could ignore the warning in the console.
If you need more info please contact us via https://support.auth0.com
@hzalaz i'm sending JWTs with websockets for an SPA, I don't know what you mean by "you need to know the secret used to sign the token, which won't be in your SPA for security reasons" because the secret is on the server that my SPA communicates with.
Needing my server to roundtrip to auth0 when I could just use the info in a JWT sounds like a big step backwards for me :(
@hzalaz also the documentation on how to get a JWT out of a hosted login page (instead of lock, which is no longer themeable so we're looking for alternatives) is non-existent.
also the documentation on how to get a JWT out of a hosted login page (instead of lock, which is no longer themeable so we're looking for alternatives) is non-existent.
Here is a generic guide on how to call the hosted login page and parse the result in the redirect url. In auth0.js is a call to authorize(options) to redirect to the hosted login page and parseHash(options, callback) to parse the result. The example in this repo performs the same flow.
About the customization, the hosted login page also uses Lock so the customizations options are the same. I don't know what type of customization you want to achieve and we know we limited what can be done via JS options but if you want, you can tweak the CSS of Lock (just always require the full version of Lock e.g. 10.9.1).
i'm sending JWTs with websockets for an SPA, I don't know what you mean by "you need to know the secret used to sign the token, which won't be in your SPA for security reasons" because the secret is on the server that my SPA communicates with.
Needing my server to roundtrip to auth0 when I could just use the info in a JWT sounds like a big step backwards for me :(
Not sure what is your setup in your app but if you receive a token from an untrusted source, e.g. the url hash fragment you need to validate the token. The only way to validate a JWT is either calling to an endpoint that can validate it or validate it yourself by verifying it's signature (and claims). In order to validate the signature of a token, you need the signing key used to sign it. If it's signed using a symmetric algorithm a shared secret is required and if you put that in your SPA anyone can read it and generate valid tokens, so the only secure way of validating a token is calling an endpoint (or using asymmetric alg like RS256 that allows you to validate using a public key).
If the JWT you talk about is the id_token you get from auth0, you need to call /tokeninfo from your SPA to validate it. In the case you are performing the Auth against Auth0 and sending the id_token via web socket, you could validate the signature of the token server side and send it back to the SPA. (In this case I'd recommend sending the profile information you need via web socket to the spa instead of the token).
On the other hand if the JWT is the token used to call the API you can rely on the API itself to validate it and reject your call if it's invalid.
For better support I'd recommend using https://support.auth0.com since Github is used mostly for issues with the libraries (and we can't share private data in the comments 馃槃 )
Hope this helps @thedavidmeister
@hzalaz
Here is a generic guide on how to call the hosted login page and parse the result in the redirect url.
Neither this guide, nor any of the other guides I could find, include a few key pieces of info (hence this issue):
responseType to id_token you will only get an access token unless you also specify a scope (openid is probably the simplest default, seems to behave like lock's default) but scope is listed as optional everywhere I've looked and nothing mentions that it is coupled to JWT handlingAbout the customization, the hosted login page also uses Lock so the customizations options are the same.
Yes, but in previous versions of lock I could set theme to false and it would strip away most of the styles from auth0. This meant I could add my own CSS to make it look the way that I want.
With this option removed, I now have to deal with how my CSS rules interact with auth0 CSS rules, which is a deal breaker for me. Overriding existing CSS and adding fresh CSS are like night and day, both in terms of overall complexity and maintainability. In light of that, I opted to try the hosted page as it seemed the easiest way to reliably sandbox your CSS and my CSS - this way, at least I'm guaranteed that your styles will always be as you intended and vice versa, rather than attempt some weird hybrid solution that would potentially break every minor version (your words, not mine - https://auth0.com/docs/libraries/lock/v10/ui-customization#overriding-css).
I either want it to look exactly like my site (no CSS from auth0), or exactly like your branding (no CSS from my site), but nothing in between, and I want that without repeatedly spending time/money on dev/QA for this one 3rd party widget.
Pragmatically, an embedded lock is now useless to me as the overhead of constantly re-assessing CSS overrides is higher than the cost of investigating alternatives (even if an alternative is as simple as just putting lock in a page hosted elsewhere).
If it's signed using a symmetric algorithm a shared secret is required and if you put that in your SPA anyone can read it and generate valid tokens, so the only secure way of validating a token is calling an endpoint
I put a shared secret on my websocket server and it rejects any connections without a JWT that buddy auth is happy with https://github.com/funcool/buddy-auth. I thought that would have been enough? Obviously putting the shared secret in the client side code is a no-no but so is putting anything else that requires authorization to access, so... I don't see the problem that is faced in an SPA that isn't faced everywhere else? you authenticate/authorize against the JWT before sending sensitive data to the client and you put the shared secret on the thing that sends sensitive data - what about an SPA causes problems here?
Validating a token in the browser before deciding to take or not take a sensitive action is pointless not because of what key (private vs. public) you've chosen but because JS is mutable and the function/logic that makes the sensitive decision can be overwritten by the user to always return true, regardless of the validity of any tokens along the way.
(or using asymmetric alg like RS256 that allows you to validate using a public key)
Hitting walls trying to get buddy to be happy with the certs I found in my account, https://github.com/funcool/buddy-core/issues/48 but that is probably a different issue and i'm not sure if it sits with auth0 or buddy or myself at this point...
I'll probably have to try v7 of the SDK in the meantime as it apparently supports HS256 still https://github.com/auth0/auth0.js/issues/305
(In this case I'd recommend sending the profile information you need via web socket to the spa instead of the token)
I use the JWT to decide whether to open the websocket at all. Don't really care if someone wants to spoof a JWT in their own browser, but sensitive data is only sent down websocket if the server behind the WS is happy that the JWT is OK (which it checks with the secret key, no round trip to auth0 required and I want to keep it that way)
@thedavidmeister I don't want to deviate a lot from the original topic of the issue so I'd answer about the jwt.
auth0.js validates that the id_token is valid (claims & signature) and that is our secure default. If you want to send that along to a server to validate even it's ok but not all will do that by default. To avoid the validation you can just parse the url fragment yourself, is just a couple lines of code and extract the id_token to send it via your web socket.
@hzalaz i'm just confused as to why validating the jwt browser side is considered OK, even with a public key?
what scenario does that cover off?
Most helpful comment
@salmanm we are in the process of introducing the API Authorization feature. This is an important shift with regards of the usage of id_token and access_token. This required a refactoring of our authentication pipeline and one of the consequences is that the access_token takes more relevance than the id_token. As a consequence also, the use of the endpoint /tokeninfo will be deprecated in favor of the use of /userinfo with the
access_tokeninstead.My recommendation would be to use the new pipeline. You can enable it by going to Account Settings => OAuth 2.0 API Authorization. These are some of the things that you will need to change:
audienceparameter in Lock to specify what API you need access to (make sure to create that API in the dashboard)getUserInfo, id_token is not needed.silentAuthenticationto refresh the access_token if it expiredFor the record, id_token will continue to work fine, but it's not what we will recommend going forward for talking to APIs. Specially, in light with the introduction to third party clients consuming your API. We will release a proper migration guide soon that will explain this in more detail, but wanted to give you a preview, since it created this confusion.