Nuxt JS - Login via API auth methods - vue.js

I use to login via schema configuration (nuxt.config.js):
strategies: {
/**
* #description OAuth 2.0 authentication scheme
* {#link https://auth.nuxtjs.org/reference/schemes/oauth2}
*/
keycloak: {
_scheme: 'oauth2',
client_id: CLIENT_ID,
authorization_endpoint: NUXT_ENV_AUTH_LOGIN,
userinfo_endpoint: NUXT_ENV_AUTH_USER_INFO_ENDPOINT,
access_token_endpoint: NUXT_ENV_AUTH_ACCESS_TOKEN_ENDPOINT,
response_type: 'token id_token',
token_type: 'Bearer',
token_key: 'access_token',
scope: ['openid', 'profile', 'email'],
},
},
and it work perfectly using the classic form login.
Now i would like to login a user without a form but starting from a valid access_token generated by a CURL (curl or whatever....).
At the moment i can't figure out how to make it work. I tried to invoke methods like explained here https://auth.nuxtjs.org/api/auth/#refreshtokens but without a good result.
What's required to be loggog in, i suppose is to have a token set into localStorage and cookie (as i see post a normal login) and set the user data into the nuxt store.
Thank you for any advice.

Related

OIDC-react signtOut doesn't end Cognito session

My stack: oidc-react, Amazon Cognito
When I log out on the site and call auth.signOut();, the userManager signs out the user and redirects to the login page, but when you log in again by calling auth.signIn(); makes a request to Cognito with the token it has, but won't ask for credentials and logs the user in, I guess because the user still has a running session with the same token, if I am right. It only asks for login credentials after an hour because the session expires after 60minutes.
I want Congito to ask for credentials after signing out. I've tried passing the config these options after some research, but doesn't seem to be working:
revokeTokenTypes: (["access_token", "refresh_token"]),
revokeTokensOnSignout: true,
automaticSilentRenew: false,
monitorSession: true
This is the OIDC setup I pass to the provider:
const oidcConfig: AuthProviderProps = {
onSignIn: (user: User | null) => {
console.log("onSignIn");
},
onSignOut: (options: AuthProviderSignOutProps | undefined) => {
console.log('onSignOut');
},
autoSignIn: false,
loadUserInfo: true,
postLogoutRedirectUri: "localhost:3000/",
automaticSilentRenew: false,
authority: "https://" + process.env.REACT_APP_AWS_COGNITO_DOMAIN,
clientId: process.env.REACT_APP_AWS_COGNITO_CLIENT_ID,
redirectUri: window.location.origin,
responseType: 'code',
userManager: new UserManager({
authority: "https://" + process.env.REACT_APP_AWS_COGNITO_DOMAIN,
client_id: process.env.REACT_APP_AWS_COGNITO_CLIENT_ID!,
redirect_uri: window.location.origin,
revokeTokenTypes: (["access_token", "refresh_token"]),
revokeTokensOnSignout: true,
automaticSilentRenew: false,
monitorSession: true
})
};
AWS Cognito does not yet implement the RP Initiated Logout specification or return an end_session_endpoint from its OpenID Connect discovery endpoint. I expect this is your problem, since the library is probably implemented in terms of these standards.
Instead, AWS Cognito uses these parameters and a /logout endpoint. In my apps I have implemented Cognito logout by forming a URL like this, then redirecting to it by setting location.href to the URL value:
public buildLogoutUrl(): string {
const logoutReturnUri = encodeURIComponent(this._configuration.postLogoutRedirectUri);
const clientId = encodeURIComponent(this._configuration.clientId);
return `${this._configuration.logoutEndpoint}?client_id=${clientId}&logout_uri=${logoutReturnUri}`;
}
This will enable you to end the Cognito session and force the user to sign in again. It will also enable you to return to a specific location within your app, such as a /loggedout view.

invalid_grant exchanging authorization code for access and refresh tokens

My application is using OAuth to access the Youtube Data API. My OAuth callback is written in node and uses the OAuth2Client class from the "googleapis" npm package to exchange the authorization code for the access and refresh tokens.
Everything was working fine up to last week until suddenly I started getting the "invalid_grant" response during the authorization code exchange. I have tried everything to resolve this and am running out of ideas. My callback executes as a cloud function so I don't think that it would be out of sync with NTP.
My OAuth consent screen is in "Testing" mode and my email address is included in the test users. The odd thing is that even though the authorization code exchange fails, my Google account's "Third-party apps with account access" section lists my application as if the handshake succeeded.
Is there a limit to how many refresh tokens can be minted for my application? I am testing my implementation of incremental authorization so I have been going through the OAuth flow often.
Edit
I've included my code for generating the auth URL and exchanging the authorization code below. The invalid_grant occurs during the call to "oauth2.getToken"
async startFlow(scopes: string[], state: string): Promise<AuthFlow> {
const codes = await oauth2.generateCodeVerifierAsync();
const href = oauth2.generateAuthUrl({
scope: scopes,
state,
access_type: 'offline',
include_granted_scopes: true,
prompt: 'consent',
code_challenge_method: CodeChallengeMethod.S256,
code_challenge: codes.codeChallenge
});
return { href, code_verifier: codes.codeVerifier };
}
async finishFlow(code: string, verifier: string): Promise<Tokens> {
const tokens = await oauth2.getToken({ code, codeVerifier: verifier })
return {
refresh_token: tokens.tokens.refresh_token!,
access_token: tokens.tokens.access_token!,
expires_in: tokens.tokens.expiry_date!,
token_type: 'Bearer',
scopes: tokens.tokens.scope!.split(' ')
};
}
"oauth2" is an instance of OAuth2Client from "google-auth-library". I initialize it here:
export const oauth2 = new google.auth.OAuth2({
clientId: YT_CLIENT_ID,
clientSecret: YT_CLIENT_SECRET,
redirectUri: `${APP_URI}/oauth`
});
Looking at the logs, the only out of the ordinary thing I notice is that the application/x-www-form-urlencoded body looks slightly different than the example https://developers.google.com/identity/protocols/oauth2/web-server#exchange-authorization-code
The POST request to "https://oauth2.googleapis.com/token" ends up looking like this:
code=4%2F0AX4XfWiKHVnsavUH7en0TywjPJVRyJ9aGN-JR8CAAcAG7dT-THxyWQNcxd769nzaHLUb8Q&client_id=XXXXXXXXXX-XXXXXXXXXXXXXXX.apps.googleusercontent.com&client_secret=XXXXXX-XXXXXXXXXXXXXXX-XX_XXX&redirect_uri=https%3A%2F%2Fapp.example.com%2Foauth&grant_type=authorization_code&code_verifier=KjOBmr4D9ISLPSE4claEBWr3UN-bKdPHZa8BBcQvcmajfr9RhWrgt7G429PLEpsP7oGzFGnBICu3HgWaHPsLhMkGBuQ2GmHHiB4OpY2F0rJ06wkpCjV2cCTDdpfRY~Ej
Notice that the "/" characters are not percent-encoded in the official example, but they are in my requests. Could this actually be the issue? I don't see how the official google auth library would have an issue this large.
The most common cause for the invalid_grant error is your refresh token expiring.
If you check oauth2#expiration you will see the following
A Google Cloud Platform project with an OAuth consent screen configured for an external user type and a publishing status of "Testing" is issued a refresh token expiring in 7 days.
Once you set your project to production your refresh tokens will stop expiring.
Is there a limit to how many refresh tokens can be minted for my application?
No but you have a limit of 100 test users.

Spartacus 3.2 connect with Auth0

I am trying to connect Spartacus 3.2 with Auth0. With below config I am able to successful login from Auth0
provideConfig(<AuthConfig>{authentication: {
OAuthLibConfig: {
responseType: 'token',
redirectUri: redirectURL,
},
baseUrl: 'https://DomainName',
client_id: 'clientID',
loginUrl: '/authorize',
}})
Issue is:
How to pass accesstoken bearer token (Authorization) and idtoken in headers that is from Auth0? in every page call.
Can I please know how to solve this?

Programmatically authenticate in Auth0

I'm setting up cypress.io to test a react app. I'm trying to programmatically authenticate with Auth0 Lock so I don't have to test their UI. Here are the steps:
POST to https://[auth0-domain].com/usernamepassword/login
client_id: "",
client_secret: "",
audience: "audience",
redirectUri: "http://[auth0-domain].com:8383/callback",
scope: "openid email crud:all",
protocol: "oauth2",
sso: true,
username: "",
password: "",
connection: "conn",
tenant: "tenant",
popup: false,
Collect returned form data
POST to https://[auth0-domain].com/login/callback
wa=wsignin1.0&wresult=token&wctx=metastuff
The first steps works but in the third step I'm able to post to login/callback but I get an HTML page with this error message:
Looks like something went wrong! There could be a misconfiguration in the system or a service outage. We track these errors automatically, but if the problem persists feel free to contact us with this tracking id: <b>e88e08e43b7cdee78458</b>.<br/>Please try again.
I'm wondering if there is something with Auth0 blocking me from doing this or if I'm not sending the correct data/header.
I ended up using the auth0-js module which calls the auth0 callback. Then I use 'should' to wait for the localStorage to be set:
import auth0 from 'auth0-js';
import url from 'url';
Cypress.Commands.add('login', () => {
const auth = new auth0.WebAuth({
audience: 'http://audience',
domain: 'domain.auth0.com',
clientID: 'qqqqqqqqqqqq',
redirectUri: 'http://localhost/callback',
responseType: 'token id_token',
scope: 'openid email profile name username groups roles',
sso: true
});
auth.login({username: 'username', password: 'pass'});
cy.window().its('localStorage.user_profile').should('exist')
});

In auth0 lock, how to refresh the id_token?

I am building a cordova mobile app and trying to use the auth0 lock API. I am having trouble with the refresh token. I can retreive the refresh token in the authResult but cannot figure out how to actually refresh the id_token ( I suppose i could write the REST calsl myself )
In the v9 docs, it seems there used to be a method: https://auth0.com/docs/libraries/lock/v9/using-a-refresh-token
lock.getClient().refreshToken(refresh_token, function (err, delegationResult) {
// Get here the new JWT via delegationResult.id_token
});
However in lock v10 it seems this method doesn't exist any more: https://auth0.com/docs/libraries/lock/v10/api
Can anyone advise if there is a way to refresh the token using the lock API?
First, you need to either have included Auth0's script tag in your HTML:
<script src="https://cdn.auth0.com/js/lock/10.8/lock.min.js"></script>
Or, if you've installed from npm, you can require Auth0:
var Auth0 = require("auth0-js");
In V10, you create an instance of the Auth0 client (separate from the Auth0Lock instance) which has a function refreshToken():
var auth0 = new Auth0({clientID: YOUR_CLIENT_ID, domain: YOUR_AUTH0_DOMAIN});
...
auth0.refreshToken(refresh_token_here, (err, resp) => {
// resp: {expires_in: 36000, id_token: "id_token here", token_type: "Bearer"}
}
The same can also be achieved by using the getDelegationToken() function:
auth0.getDelegationToken({
client_id: YOUR_CLIENT_ID,
grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer",
refresh_token: refresh_token_here,
scope: "openid",
api_type: "auth0"
}, (err, resp) => {
// resp: {expires_in: 36000, id_token: "id_token here", token_type: "Bearer"}
});