OAuth2.0 token post request is responding 401 (invalid_client) - javascript

I am very new to the Google OAUth2.0 authentication and thus my question sounds like dumb. However, I am stuck with this problem quite a time and need your input to solve it.
I was integrating the Globus login within my app. Globus login using Google OAuth-2 protocol for authentication. According to the Globus Auth developer guide, I successfully redirect the app to their authorization service, the user can put their credential to authenticate, and the app receives the code returned from the Globus Auth server upon successful authentication. Next step is sending the code to the Token endpoint to get the access token. I used the following code:
var querystring = require('querystring');
export const logInGlobus = (payload) => {
let tokenUri = encodeURIComponent(payload.redirect_uri);
let client_id = 'out app client id'
let client_secret = 'client secret generated for authentication'
let cred = btoa(client_secret);
return axios.post('https://auth.globus.org/v2/oauth2/token',
querystring.stringify({
grant_type: 'authorization_code',
code: payload.code,
redirect_uri: tokenUri,
client_id: client_id
}),
{
headers:{
Authorization: 'Basic '+ cred,
'Content-Type': 'application/x-www-form-urlencoded'
}
})
.then(response => {
return{
res: response,
success: true
}
})
.catch(err => {
return{
res: err,
success: false
}
})
}
I am getting 401 {"error":"invalid_client"} code for this post request from the server. What am I missing?
N.B: I have tried without client secret, client id, not encoding redirect URL. No luck so far>
I would really appreciate your effort if you show me some light. Thanks for your time.
====Edited====
The error from the console at the browser is attached

I solved the problem. I had to put the client secret at the body of the post request. The following code resolves my problem.
var querystring = require('querystring');
export const logInGlobus = (payload) => {
let client_id = 'app client id'
let client_secret = 'client secret generated for authentication'
return axios.post('https://auth.globus.org/v2/oauth2/token',
querystring.stringify({
grant_type: 'authorization_code',
code: payload.code,
redirect_uri: payload.redirect_uri,
client_id: client_id,
client_secret: client_secret
}),
{
headers:{
'Content-Type': 'application/x-www-form-urlencoded'
}
})
.then(response => {
return{
res: response,
success: true
}
})
.catch(err => {
return{
res: err,
success: false
}
})
}

Related

Cypress OKTA Authenticate user with email MFA via API

So, I'm having a SPA which has Okta implemented for authentication. According to the Okta policy that is set up in place, the user(s) log in with credentials (email and password) and then are prompted to validate with a magic link or code (both sent to their primary email address). I'm trying to get around this and programmatically login through API
What I've tried so far:
a POST Request to the /api/v1/authn with the username and password (which returns a session token)
then a GET request to /oauth2/default/v1/authorize with the clientID,sessionToken,redirectUri,scope which should return the access and id tokens from my understanding...
This last request just redirect back to the login page.
Cypress.Commands.add('oktaLogin', () => {
const optionsSessionToken = {
method: 'POST',
url: `https://${Cypress.env('okta_domain')}/api/v1/authn`,
body: {
username: Cypress.env('okta_username'),
password: Cypress.env('okta_password'),
options: {
warnBeforePasswordExpired: 'true'
}
}
}
cy.request(optionsSessionToken).then(response => {
const sessionToken = response.body.sessionToken;
const qs = {
client_id: Cypress.env('okta_clientid'),
redirect_uri: `https://${Cypress.env('baseURL')}/callback`,
code_challenge_method: 'S256',
responseType: ['id_token','token'],
scope: ['openid', 'profile', 'email'],
sessionToken: sessionToken,
}
cy.request({
method: 'GET',
url: `https://${Cypress.env('okta_domain')}/oauth2/default/v1/authorize`,
form: true,
followRedirect: true,
qs: qs
}).then(response2 => {
//tokens should be available here?
cy.log(response2.body)}) //returns HTML back to login.
});
})

Discord OAUTH error: 'unsupported_grant_type',

I am trying to implement a Discord-Login onto my Website. Unfortunately I am getting an error from discord.
Does anybody see, whats wrong with my code?
FYI: I am already get back the code from discord. So my first request is working fine.
What I want to do with the Data:
I want to get the user_ID so I can add groups to the user on my Discord Server.
ERROR:
error: 'unsupported_grant_type',
error_description: 'Grant type None is not supported'
Code:
router.get('/account-settings/connections/discord/callback', (async (req, res) => {
const code = await req.query.code;
const creds = btoa(`${CLIENT_ID}:${CLIENT_SECRET}`);
fetch(`https://discordapp.com/api/oauth2/token`, {
method: "POST",
headers: {
Authorization: `Basic ${creds}`,
},
body: querystring.stringify({
grant_type: 'authorization_code',
code: code,
redirect_uri: dis_redirect
}),
})
.then((res) => res.json())
.then((body) => console.log(body));
})
Thank you very much in advance!!!
The best regards,
Joshy
Okay for everybody else, who has this problem. I was able to fix this with parsing all information in the body and setting up the content type in the headers. Here is a working code:
let params = new URLSearchParams();
params.append('client_id', CLIENT_ID);
params.append('client_secret', CLIENT_SECRET);
params.append('grant_type', 'authorization_code');
params.append('code', code);
params.append('redirect_uri', dis_redirect);
fetch('https://discord.com/api/oauth2/token', {
method: 'post',
body: params,
headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Accept': 'application/json' },
}).then(r => r.json()).then(async Response => {
In the code variable, I have stored the request query, I am getting back from TwithOauth (After autorization of the user).
Client ID and Client Secret you will get from your Discord Application. The dis_redirect virable is containing my redirection link, which is just blank string of my Link, I have setup to get the router.
Nothing more is needed.
You will get a JSON responded, which you can work with. If you want to get the users data (like me) this following code is what you searching for:
let refresh_token = Response.refresh_token;
let accessToken = Response.access_token;
var site = await fetch("https://discord.com/api/v9/users/#me", {
method: 'GET',
headers: {'Authorization': `Bearer ${accessToken}`}
});
var response = await site.json();
console.log(response);
});
This code you will place directly in the new opened async function. There you have it. All users data, you will need.
I hope I was able to help someone. If you have any questions, just let me know!
The best regards,
Joshy

Axios POST request returns 404 error when sending to Node.js API

I am developing a web application using a React frontend and a Node.js backend. The frontend sends a POST request to the backend using Axios like this:
Register.js
...
handleSubmit = (e) => {
e.preventDefault();
const { email, password, name, dateofbirth } = this.state;
const user = { email, password, name, dateofbirth };
const url = "http://localhost:9000/register";
axios
.post(url, user, {
headers: {
"Content-Type": "application/json",
},
})
.then((response) => console.log(response))
.catch((error) => {
console.error("You have made a big error. " + error);
console.log(user);
});
};
...
While the backend receives the request like this:
./routes/register.js
...
router.post("/register", async (req, res) => {
console.log("Inside Home Login");
res.writeHead(200, {
"Content-Type": "application/json",
});
console.log("Users : ", JSON.stringify(users));
res.end(JSON.stringify(users));
})
...
However I get the error "POST http://localhost:9000/register 404 (Not Found)" upon trying to send anything.
My guess would be that you are routing in your index.js. If you can provide a code sample to figure it out.
If so, the thing is defining a routing like,
app.use('/register', yourImportedVariable);
does define a route at http://localhost:9000/register.
So, if in your routes/register.js file you define a GET endpoint with '/register' your front-end call must be http://localhost:9000/register/register
To fix it, either rename your route as '/', or fix your front-end call with the above url.

How to automate the OAuth 2.0 token generation using Artillery?

I want to automate the OAuth 2.0 token automatically via javascript. Is there any way I can do that and obtain the token to use it in the artillery scrtips.
For the OAuth token generation I have below details:
Auth URL
Client ID
Scope
It is done by client authentication credentials.
Below is the sample code I am using to generate the token:
var ClientOAuth2 = require('client-oauth2')
var Auth = new ClientOAuth2({
clientId: 'ClientID',
accessTokenUri: 'https://Auth_URL/v2.0/token',
authorizationUri: 'https://Auth_URL/v2.0/authorize',
redirectUri: 'https://Auth_URL/',
scope: 'api://Scope/access_as_user'
})
Auth.owner.getToken('Username', 'password')
.then(async (user) => {
await console.log(user) //=> { accessToken: '...', tokenType: 'bearer', ... }
}).catch((e) => { console.log('error show',e); })
.finally( () => console.log('end'));
You can declare your custom JS files which will be triggered every time before the request:
Your YAML file can be like here:
config:
target: "https://baseUrl.com"
phases:
- duration: 60
arrivalRate: 100
processor: "./customFile.js"
scenarios:
- flow:
- post:
url: "/pathInYourApi"
headers:
Content-Type: "application/json"
Accept: application/json
json: {}
beforeRequest: "beforeRequest"
and then your customFile.js script:
module.exports = {
beforeRequest: beforeRequest,
};
function beforeRequest(requestParams, context, ee, next) {
// Call your OAuth client, and after you obtain token you can assign it to requestParams Authorization header
// eg. requestParams.headers.Authorization = `Bearer + ${token}`
return next(); // MUST be called for the scenario to continue
}

Cannot get an accessToken from LinkedIn API due to 'redirect_uri' error

I am trying to achieve LinkedIn sign in using their API provided by Oauth2.0
According to docs - https://learn.microsoft.com/en-us/linkedin/shared/authentication/authorization-code-flow?context=linkedin/consumer/context
I am able to get access code (1 step). Afterwards I stuck on completing new request with error (to get an accessToken) - https://gyazo.com/abe24d7294aa4c1b9d8be9a101747ee2
Although I did configure my redirect URI in LinkedIn dev dashboard - https://gyazo.com/c533a589465042342d79438eab02d2a2
I've tried querystring.stringify method from query-string package
function trigerLogin() {
const accessToken = localStorage.getItem('AccessCode');
if (!accessToken) {
window.open('https://www.linkedin.com/uas/oauth2/authorization?response_type=code&state=DCEeFWf45A53sdfKef424&client_id=*************&redirect_uri=http%3A%2F%2Flocalhost%3A4000%2Fcallback&scope=r_liteprofile+r_emailaddress', '_blank', 'top=100, left=200, height=500, width=500');
}
axios.post('https://www.linkedin.com/oauth/v2/accessToken', querystring.stringify({
client_id: '*************', // for safety reasons
grant_type: 'authorization_code',
code: accessToken,
redirect_uri: 'http://localhost:4000/callback',
client_secret: '**************' // for safety reasons
}))
.then(function (response) {
console.log(response);
})
.catch(error => {console.log(error)})
}
So I cannot get a response with a token with which I can work further
Thank you in advance!

Categories

Resources