Setup following in nuxt.config.js:
/*
** Auth module configuration
*/
auth: {
strategies: {
auth0: {
domain: 'xxx',
client_id: 'xxx',
scope: ['openid', 'profile', 'email'],
response_type: 'id_token token',
token_key: 'id_token'
}
}
},
Go to your Login page.
User is redirected to Auth0. When the user is returned, both the token and id_token should be stored as a cookie and in localStorage, and $auth.state.loggedIn should be true.
User is redirected to Auth0. When the user is returned, only the id_token is set and $auth.state.loggedIn returns false. A GET call is made to https://xxx.eu.auth0.com/userinfo, which returned a 401 {"error":"unauthorized","error_description":"invalid credentials"}, because the call is made with the id_token as a Bearer token and auth0 expects the token.
See https://cmty.app/nuxt/auth-module/issues/c342 for full story.
If you remove the id_token from the config, the auth0 flow works. However i need the JWT for talking to my API.
Supported response_type for auth0 is currently code. Any reason you need both tokens?
Just getting a token (and not also the id_token) as a response_type fixes the auth0 flow. The problem is that I cannot authenticate with my API, because for that i need the id_token (the JWT).
auth0: {
domain: "xxx",
client_id: "xxx",
scope: ["openid", "profile", "email"],
response_type: "token"
}
If I add the id_token, I'm getting the correct JWT for authentication with my API, but I get an endless loop between the callback URL and the login URL. When I'm redirected from my website, to auth0, back to my website, I can see the cookie created and the localStorage populated with the correct Id_token, but $auth.state.loggedIn is always false (the user is not set). Therefore, an infinite loop is created going from login -> auth0 -> callback -> login -> auth0 > etc.
auth0: {
domain: 'xxx',
client_id: 'xxx',
scope: ['openid', 'profile', 'email'],
response_type: 'id_token token',
token_key: 'id_token'
}
With token_key: 'id_token' I noticed a GET call was made to https://xxx.eu.auth0.com/userinfo, which returned a 401 {"error":"unauthorized","error_description":"invalid credentials"}.
So I guess I need to make the userinfo call with the token instead of the id_token. The problem is that although I call both id_token and token, I can only see the id_token stored in the localStorage and cookies.
In @nuxtjs/auth/lib/schemes/oauth2.js it looks like it's only storing the value in the token_key option, and not the multiple values in response_type:
Line 128:
// accessToken/idToken
let token = parsedQuery[this.options.token_key || 'access_token']
If I put a console.log around:
Line 126:
const parsedQuery = Object.assign({}, search, hash)
I'm getting the object below, which means both id_token and token are available, but just the one set in token_key is stored.
{
"": "",
"access_token": "xxx",
"scope": "openid profile email",
"expires_in": "7200",
"token_type": "Bearer",
"state": "xxx",
"id_token": "xxx"
}
If i change the response_type to code, and i remove the token_key, then the flow is stuck at the callback url page. Im not authenticated $auth.state.loggedIn is false and I'm also not redirected.
According to the docs:
The ID Token is a JSON Web Token (JWT) that contains user profile information (such as the user's name and email) which is represented in the form of claims. These claims are statements about the user, which can be trusted if the consumer of the token can verify its signature.
Which means this id_token itself contains user info object. This is not useful for the auth module as a user object by is retrieved from /userinfo endpoint via access_token after each page load. (Not by parsing JWT) So we don't have to set token_key to id_token.
The problem is that I cannot authenticate with my API, because for that I need the id_token (the JWT).
How is your API authenticating with auth0 that requires id token? Can you please share a code snippet or explain more about use case?
Thanks for the reply!
I'm using the Symfony bundle provided by Auth0. The UserProvider can be found here. The function is called function loadUserByJWT($jwt) on line 26.
I started to read more on the auth0 website and it says here:
How NOT to use tokens
Now that we've seen some ways in which we can use tokens, let's talk about when they should
not be used.Access Tokens must never be used for authentication. Access Tokens cannot tell us
if the user has authenticated. The only user information the Access Token possesses
is the user ID, located in the sub claim.ID Tokens should not be used to gain access to an API. Each token contains information for the
intended audience (which is usually the recipient). Per the OpenID Connect specification, the
audience of the ID Token (indicated by the aud claim) must be the client ID of the application making
the authentication request. If this is not the case, you should not trust the token. Conversely, an API
expects a token with the aud value to equal the API's unique identifier. Therefore, unless you
maintain control over both the application and the API, sending an ID Token to an API will generally
not work. Furthermore, the ID Token is signed with a secret known only to the application itself. If an
API were to accept an ID Token, it would have no way of knowing if the application has modified the
token (such as adding more scopes) and resigned it.
If i read it correctly, the second tab is my implementation. But this is the behavior by auth0's own PHP implementation. Need to read more on this.
We have two ways:
For auth module, you may disable userinfo_endpoint by setting false value, use id_token and use your API to validate the id_token JWT signature and return user object (as of example) This means $auth.user is not usable but you have to implement it your own. I may add support for user extraction from token in future releases but not a good idea for security and not possible as of now.
Use token (default) flow and obtain access_token. Then, In symphony UserProvider, instead of decoding JWT token using provided token to make a request to /userinfo and validate token / obtain user. The downside of this approach is an extra request for the backend to validate user but works as of now and is a reasonably secure approach.
Ok, found it. It was due to bad configuration on my part. I just recently moved my Vue project to Nuxt, and since everything was working before I thought the issue was with this module. Thanks for making me go back to the reading material.
audience in nuxt/auth was not set (it got lost somewhere in the migration to nuxt). When I set the correct audience, the token returns a JWT formatted token.audience of my API was set to the client_id, which makes no sense at all. But that is probably why I needed the id_token specifically for talking with my API.After I made these changes, im good again. Thanks!!
@darthf1 I'm struggling with same issue. Can you elaborate on your resolution? (And maybe update the docs?)
I'm trying to use Nuxt + Hasura and right now I'm just manually grabbing the id_token when Auth0 redirects. I'd prefer if it just all worked automagically via this module.
The resolution was to fix a bad config on my end. After i set the correct audience, the flow was fixed.
Can you be more explicit? What is an audience? How do you set the audience? What does your config look like?
If you can at least share your config, that would be super helpful! Thanks :)
More can be found here in the docs: https://auth.nuxtjs.org/providers/auth0.html#obtaining-client-id-domain-and-audience
@tonjohn could you solve this ? Im struggling with the same thing.
@tcaraccia @darthf1
I had the same problem as you, I fixed it (after looong search and pain, I mean learning...)
the audience is in the auth0 identifier for your tenant

then the auth module config in nuxt.config.js is this:
auth: {
redirect: {
callback: '/callback',
},
strategies: {
local: false,
auth0: {
domain: 'nuxt-apollo-hasura.eu.auth0.com',
client_id: 'ap...',
audience: 'https://nuxt-apollo-hasura.eu.auth0.com/api/v2/',
},
},
},
Since calls to /userinfo are rate limited to about 5 per minute by Auth0, it seems to be a good idea to intercept and use the id_token, since it is automatically provided at login by Auth0 anyway.
Most helpful comment
@tcaraccia @darthf1
I had the same problem as you, I fixed it (after looong search and pain, I mean learning...)
the audience is in the auth0 identifier for your tenant
then the auth module config in nuxt.config.js is this: