I was doing auth0's code grant flow with pkce and there was an api call for fetching tokens in auth0 docs like this -
var request = require("request");
var options = {
method: 'POST',
url: 'https://YOUR_DOMAIN/oauth/token',
headers: {'content-type': 'application/x-www-form-urlencoded'},
form: {
grant_type: 'authorization_code',
client_id: 'YOUR_CLIENT_ID',
code_verifier: 'YOUR_GENERATED_CODE_VERIFIER',
code: 'YOUR_AUTHORIZATION_CODE',
redirect_uri: 'https://YOUR_APP/callback'
}
};
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
Now this successfully works and gets tokens, but if I try to do same request with axios it fails and returns 401 unautorized error. Can anyone tell me what I am doing wrong? My guess is that I am not sending the body correctly.
const axios = require("axios");
async function getTokens() {
const body = {
grant_type: 'authorization_code',
client_id: 'YOUR_CLIENT_ID',
code_verifier: 'YOUR_GENERATED_CODE_VERIFIER',
code: 'YOUR_AUTHORIZATION_CODE',
redirect_uri: 'https://YOUR_APP/callback'
};
const headers = {'content-type': 'application/x-www-form-urlencoded'};
const data = axios.post("https://YOUR_DOMAIN/oauth/token", body, {headers});
console.log(data);
}
Thank you in advance for your help.
Related
I'm trying to fetch the OAuth access token with the lambda function but getting fhe following error:
data: {
error: 'invalid_request',
error_description: 'Missing or duplicate parameters'
}
This is the code:
var axios = require("axios").default;
exports.handler = async (event) => {
var options = {
method: 'POST',
url: 'https://******/auth/oauth/v2/token',
headers: {'content-type': 'application/x-www-form-urlencoded'},
data: {
grant_type: 'client_credentials',
client_id: '*********',
client_secret: '******'
}
};
try {
const resp = await axios.request(options);
console.log(resp.data)
} catch (err){
console.error(err);
}
};
When I try to run the request with the Postman it returns the valid token.
As stated by #derpirscher, I had to properly serialize the data object using 'qs' library. After that I was able to fetch the access token successfully.
var axios = require("axios").default;
const qs = require('qs');
exports.handler = async (event) => {
var data = {
grant_type: 'client_credentials',
client_id: '*********',
client_secret: '************'
};
var options = {
method: 'POST',
url: 'https://************/auth/oauth/v2/token',
headers: {'content-type': 'application/x-www-form-urlencoded'},
data: qs.stringify(data)
};
try {
const resp = await axios.request(options);
console.log(resp.data)
} catch (err){
console.error(err);
}
};
I have this microsoft graph authentication code, making what I think is the same request using axios and then using request. However, the axios request fails with 404, whereas the request request succeeds. What am I doing wrong with axios?
const axios = require('axios')
const request = require("request");
const FormData = require('form-data');
const data = FormData()
data.append('client_id', XXXXXXXXXXX),
data.append('client_secret', XXXXXXXXX),
data.append('scope', "https://graph.microsoft.com/.default"),
data.append('grant_type', 'client_credentials')
const requestParams = {
client_id: logins.activedirectory.clientID,
client_secret: logins.activedirectory.clientSecret,
scope: "https://graph.microsoft.com/.default",
grant_type: "client_credentials",
};
const endpoint = "https://login.microsoftonline.com/" + XXXXXXXX + "/oauth2/v2.0/token";
///////// AXIOS //////////
axios({
method: 'post',
url: endpoint,
data: data,
headers: {'Content-Type': 'application/x-www-form-urlencoded' }
})
.then(function (response) {
console.log(response);
})
.catch(function (response) {
console.log(response);
});
///////// REQUEST /////////
request.post({ url:endpoint, form: requestParams }, function (err, response, body) {
if (err) {
console.log(err);
} else {
console.log(body);
}
});
Here is a basic code:
const superagent = require('superagent');
superagent.get('https://api.arabam.com/pp/step')
.query({ apikey: '_V85Kref7xGZHc1XRpUmOhDDd07zhZTOvUSIbJe_sSNHSDV79EjODA==' })
.end((err, res) => {
if (err) { return console.log(err); }
console.log(res.body.url);
console.log(res.body.explanation);
});
But apikey is header rather than query. How do I send it as a header?
Edit:
I have tried using request module and it simply says that I'm unable to access it
var request = require("request");
request({
uri: "https://api.arabam.com/pp/step",
method: "GET",
'Content-Type' : "application/json",
apikey: "_V85Kref7xGZHc1XRpUmOhDDd07zhZTOvUSIbJe_sSNHSDV79EjODA=="
}, function(error, response, body) {
console.log(body);
});
It says unauthorized to access
From the Setting header fields doc, you should use
request.set('apikey', '_V85Kref7xGZHc1XRpUmOhDDd07zhZTOvUSIbJe_sSNHSDV79EjODA==')
to set the header field.
This is the server side code that tried to make a POST request to Instagram to get an access token
app.get('/instagram/json', (req, res) => {
axios({
method: 'post',
url: 'https://api.instagram.com/oauth/access_token',
data: {
'client_id': instagramClientId,
'client_secret': instagramClientSecret,
'grant_type': 'authorization_code',
'redirect_uri': 'http://localhost:3000',
'code': instagramCode
}
}).then((response) => {
console.log(response);
}).catch((e) => {
console.log(e);
});
});
This is the error response I get. It tells me that "client_id" is required despite I clearly have provided it.
data:
{ error_type: 'OAuthException',
code: 400,
error_message: 'You must provide a client_id' } } }
Here is a solution:
const insta_form = new URLSearchParams();
insta_form.append('client_id', 'xxx');
insta_form.append('client_secret', 'xxx');
insta_form.append('grant_type', 'authorization_code');
insta_form.append('redirect_uri', 'xxx');
insta_form.append(
'code',
'xxx'
);
await axios({
method: 'POST',
url: 'https://api.instagram.com/oauth/access_token',
data: insta_form,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
})
.then((response) => {
console.log(response);
})
.catch((err) => {
console.log(err.response);
});
}
import axios from 'axios'
import {stringify} from 'qs'
const response = await axios({
method: "post",
url: "https://api.instagram.com/oauth/access_token",
data: stringify({
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET,
grant_type: 'authorization_code',
redirect_uri: REDIRECT_URL,
code
}),
headers: { "Content-Type": 'application/x-www-form-urlencoded' },
})
Late, but since there's not a good answer on the web and took me a while:
You'd have to wrap your body inside a form-data before providing it to fetch-node's post.
Install form-data: npm install --save form-data
then:
const formData = require("form-data");
const insta_form = new formData();
insta_form.append("client_id", your client id);
insta_form.append("client_secret", your client secret);
insta_form.append("grant_type", "authorization_code");
insta_form.append("redirect_uri", your redirect uri);
insta_form.append("code", user code);
const shortTokenRes = await fetch(
"https://api.instagram.com/oauth/access_token",
{
method: "POST",
body: insta_form,
}
);
I'm making an app that is supposed to use oAuth to authenticate players from the Blizzard servers, I want to access their character info.. and I can't figure out how to ask for the secret_token. I guess I'm doing my post request wrong below is the code I'm using
app.post('/', function(req, res) {
var code = req.body.code; //this is the code i get ounce the player is redirected back to my redirect_uri
var redirectUri = "https://localhost:3000/oauth_callback.html";
var scope = "wow.profile";
var key = "they client_id i was given";
var secret = "they secret I was given";
var grantType = "authorization_code";
var tokenUri = "https://us.battle.net/oauth/token";
var uriBody = "?client_id=" + key + "&client_secret=" + secret + "&grant_type=authorization_code&code=" + code + "&redirect_uri=" + redirectUri + "&scope=" + scope;
request({
url: tokenUri, //URL to hit
method: 'POST',
headers: {
'Content-Type': "application/x-www-form-urlencoded",
},
body: uriBody //Set the body as a string
}, function(error, response, body){
if(error) {
console.log(error);
} else {
console.log(response.statusCode, body);
}
});
so basically I'm getting the code making a post request to my server with it, and then triggering a post request to the blizzard server trying to exchange my code for an access token.
The error I get is:
401 '{"error":"unauthorized","error_description":"An Authentication object was not found in the SecurityContext"}'
I'm using Node.js & request.js to make the post, my guess is I'm not making a proper request post request?
I think body key is not acceptable in request.
Send data in json if content-type is JSON or form if content-type is x-www-form-urlencoded
Like this
request({
url: tokenUri, //URL to hit
method: 'POST',
headers: {
'Content-Type': "application/x-www-form-urlencoded",
},
form: uriBody //Set the body as a string
}, function(error, response, body){
if(error) {
console.log(error);
} else {
console.log(response.statusCode, body);
}
});
finally! here is how I got it to work!
qs = query-string.js library...
var token_params = qs.stringify({
client_id: key,
client_secret: secret,
code: code,
scope: scope,
grant_type: 'authorization_code',
redirect_uri: redirectUri
});
request('https://us.battle.net/oauth/token?' + token_params, function(error, response, body){
if (error) {
console.log(error);
} else {
console.log(body)
}
});