Get access token for Microsoft graph api using plain JavaScript - azure-active-directory

I try to fetch planner data using Microsoft graph api using ajax call But I am getting https://graph.microsoft.com/v1.0/me/planner/tasks 400 (Bad Request):
function requestToken() {
$.ajax({
"async": true,
"crossDomain": true,
"url": "https://cors-anywhere.herokuapp.com/https://login.microsoftonline.com/common/oauth2/v2.0/token", // Pass your tenant name instead of sharepointtechie
"method": "POST",
"headers": {
"content-type": "application/x-www-form-urlencoded"
},
"data": {
"grant_type": "client_credentials",
"client_id ": "--REDACTED--", //Provide your app id
"client_secret": "--REDACTED--",
//Provide your client secret genereated from your app
"scope ": "https://graph.microsoft.com/.default"
},
success: function (response) {
console.log(response);
token = response.access_token;
$.ajax({
url: 'https://graph.microsoft.com/v1.0/me/planner/tasks',
type: 'GET',
dataType: 'json',
beforeSend: function (xhr) {
xhr.setRequestHeader('Authorization', 'Bearer '+token+'');
},
data: {},
success: function (results) {
console.log(results);
debugger;
},
error: function (error) {
console.log("Error in getting data: " + error);
}
});
}
})
}
Looking for json data from planner but getting error code
https://graph.microsoft.com/v1.0/me/planner/tasks 400 (Bad Request) while fetching from graph api.

Firstly there are a couple of major issues with the code you've shared right now:
You should not be using Client Credentials Grant, i.e. clientId and client secret to make the call to Microsoft Graph API from your client side JavaScript code, it's only meant for confidential clients like a daemon or service.
You are anyways trying to hit the endpont https://graph.microsoft.com/v1.0/me/planner/tasks, which includes the keyword me that is valid only for a user identity. So you should try to acquire token using identity of the user who is currently signed in or prompt the user if they're not signed in.
You can make use of Microsoft Graph JavaScript Client Library to call Microsoft Graph.
The link for client library also provides good step-by-step guidance with sample code.
NOTE: please don't put your client secret or any other sensitive information as part of your question on stackoverflow. I'll edit the question for now, but you should still delete this particular secret for your application and generate new ones for any future use.

Related

Expressjs Server cannot handle Requests from the Outside

I have a ExpressJs Server with React Components. And the Server should handle Requests from Outside and one request should play a Song from the Spotify API when not currently playing.
app.post("/play", (req, res) => {
try {
// requesting to play uses query params
id = req.query.id;
currPlayingID = 0;
// get the currently playing song from the SPotify API
axios({
url: "https://api.spotify.com/v1/me/player/currently-playing",
method: "get",
headers: {
authorization: `Bearer ${access_token}`,
},
})
// set the currently Playing ID or to zero if nothing is playing
.then((response) => {
if (response.data !== null) {
currPlayingID = response.data.id;
} else {
currPlayingID = 0;
}
});
// only play the song if its not currently playing
if (id !== currPlayingID) {
// making a axios request to the Spotify API to play the Song with the ID
axios({
url: "https://api.spotify.com/v1/me/player/play/",
method: "put",
headers: {
authorization: `Bearer ${access_token}`,
},
data: {
uris: [`spotify:track:${id}`],
},
});
res.status(204);
}
} catch (error) {
res
.status(404)
.json({ message: "Couldn't get Info from Spotify API", error: error });
}
});
The Problem:
The Code works when I start the server on the device itself (so a local server on my Desktop PC), but when I start the Server on my RaspberryPI i cannot handle Requests to this endpoint /play. Yeah I updated all the IP Adresses, everywhere.
But the moer ointeresting part is using the React Client I get this error:
Failed to load resource: net::ERR_CONNECTION_REFUSED
Requesting with POSTMAN I get the following:
Mixed Content Error: The request has been blocked because it requested an insecure HTTP resource
And from a request using a python script I get on the server side:
[UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "AxiosError: Request failed with status code 400".] {
code: 'ERR_UNHANDLED_REJECTION'
}
I have no clue how to fix each error and if it is one fix. Basically I found out it is a Problem with rejeccting requests from outside localhost, because with cURL on my ssh terminal it works.
I'm learning express, so I m not an expert, but I'm looking at your errors. I will suggest you try asyncHandler module. It handles asynchronous requests and exceptions.
I faced a similar issue because while I'm sending the API request via
Axios, my token is null/empty/wrong, so make sure your token is correct
this is my request format
axios({
method:"POST",
url:"https://graph.facebook.com/v13.0/"+phon_no_id+"/message?access_token="+token,
data:{
messaging_product:"whatsapp",
to:from,
text:{
body:"Hi.. I'm Prasath"
}
},
headers:{
"Content-Type":"application/json"
}
});

Microsoft Graph API: Access Token 403 Forbidden error Using ajax call but works properly using postman

When I try to make a rest call from postman I am able to get access token but using ajax call I am getting 403 forbidden error. Appended https://cors-anywhere.herokuapp.com/ url to access token url to avoid CORS error.
const formData = new FormData();
formData.append("client_id", "client_id");
formData.append("client_secret", "S7D7Q~excS5KjBh9JnPK-afZjTjtALGTKNweP");
formData.append("grant_type", "client_credentials");
formData.append("scope", "https://graph.microsoft.com/.default");
$(document).ready(function () {
requestToken();
});
var token;
function requestToken() {
$.ajax({
async: true,
crossDomain: true,
credentials: "include",
url: "https://cors-anywhere.herokuapp.com/https://login.microsoftonline.com/b262d1f3-4738-400d-ad54-c82cdabb6540/oauth2/v2.0/token",
method: "POST",
headers: {
"content-type": "application/x-www-form-urlencoded"
},
cache: false,
processData: false,
contentType: false,
data: formData,
success: function (response) {
console.log(response);
token = response.access_token;
},
});
}
You should not use a client credential in your front-end. That's your application's password and will be visible to anyone visiting the page. Also if that is your actual secret in the question, you should remove it and create a new one.
This URL will not work:
https://cors-anywhere.herokuapp.com/https://login.microsoftonline.com/b262d1f3-4738-400d-ad54-c82cdabb6540/oauth2/v2.0/token
The reason you get a CORS error is because Azure AD is trying to prevent you from shooting your own foot.
AAD sees the request and thinks it should not come from a browser front-end and thus denies it.
The correct way to get the token is to use MSAL.js and acquire a token on behalf of the signed in user (delegated permissions).

How to send body data with headers with axios get request

I am trying to get request from api that has a owner = value and date = value. Using Postman I can send a request with body json to get results. However when using Axios I can not get the results. How do I send body json to header and get results back. with Axios I am getting an empty response
does not work
var searchRecord = {
owner: 'wxTWH8zqSwaIXPAVsjZoRCkvjx73',
date: '2021-09-02',
};
var config = {
method: 'get',
url: 'http://localhost:3000/records/owner',
headers: {
'Content-Type': 'application/json',
},
body: searchRecord,
};
axios
.get('http://localhost:3000/records/owner', config)
.then(function (response) {
// handle success
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
})
in Postman I can send the following in the body and get the results I need
{
owner: 'wxTWH8zqSwaIXPAVsjZoRCkvjx73',
date: '2021-09-02',
}
output response will be:
{
"instantMessage": "false",
"isComplete": false,
"_id": "612e5cede496ce8f1b6a244c",
"date": "2021-08-31",
"title": "Ming first",
"description": "Test",
"remindTime": "1630432800",
"owner": "wxTWH8zqSwaIXPAVsjZoRCkvjx73",
}
I think I have the same problem.
When I'm using the postman to test my backend - everything work ok.
So the purpose is to get data from endpoint (and as body I want to provide user email):
data = {
"user_email": test#test.com
}
.get("api/test_endpoint/", config, data)
How to send body data and headers with axios get request?
Last comment in above topick "GET Body is allowed by the standards past 2014".
So finally is it possible or is it a correct practice?
Edit:
Of course I have to add:
It's possible to add needed data as part of get request url (but it's could not be login or pass!!!)
So for example logged in admin user has possibility to get data for some user via email like:
get('localhost/api/test_endpoint?user_email=test#test.com')
So why not use body as part of get request?

POST Request to Azure DevOps Rest API with Reactjs

So far I've been able to configure a method in C# that is able to hardcode a new repository in Azure DevOps, but my real goal is to create a user interface that allows the user to specify the request body which consists of the following:
name: 'nameOfRepository',
project: {
id: 'projectId'
}
The user will fill out the first input field with the desired name of the new repository. The second input field should use a GET Request that displays all available projects in your organization in a dropdown list.
I'm also using .NET Core 3.0 and believe this probably has to be done with an API controller as well, but I am not certain.
I have little to no experience with React and have no idea how and where I'm going to specify the request body and personal access token to create the repository. I would appreciate an explanation of how this works and would also appreciate a solution that could guide me in the right direction.
Azure DevOps Rest API Documentation will give you access to the platform. If you are decided to develop totally in React js. I would like to suggest to take a starter kit, mostly will cover all your basic setup to React.
Follow the below steps to get an idea of how you can achieve with react js
Need to set up OAuth in azure deops. The below link will give an idea. In the callback page, you need to store access token store
https://learn.microsoft.com/en-us/azure/devops/integrate/get-started/authentication/oauth?view=azure-devops. If you have personal auth token this is not required
Get all list of repositories using fetch or Axios API
Example with Axios:
const headers = {
'Content-Type': 'application/json',
'Authorization': 'bearer token' or 'basic personalaccesstoken'
}
axios.get('https://dev.azure.com/{organization}/{project}/_apis/git/repositories', {
headers: headers,
params: {
'api-version':'5.1'
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
Use react form to capture the input value and on submit of form, validate against the repositories, if it is new call the Axios or fetch post method to create a new repository
Example with Axios
const headers = {
'Content-Type': 'application/json',
'Authorization': 'bearer token'
}
const data = {
name: ''
parentRepository: {id: '', ....}
project: {id: '', ...}
}
axios.post('https://dev.azure.com/{organization}/{project}/_apis/git/repositories', JSON.stringify(data),
{
headers: headers,
params: {
'api-version':'5.1'
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
Similarly, you can access all the API's mentioned REST API documentation of Microsoft. link

angular and dropbox can(t get token with code flow

i have this snippet:
var req = {
method: 'POST',
url: 'https://api.dropboxapi.com/oauth2/token',
headers: {'Content-Type': 'application/json'},
data: {
'code': authCode,
'grant_type': 'authorization_code',
'client_id': 'my_id',
'client_secret': 'my_secret',
'redirect_uri':'http://localhost%3A8080/main'
}
};
return $http(req).then(function(response){
console.log(response.status);
return response;
}, function(err){
console.log(err);
});
The can always ends up in a "bad request" because ""No auth function available for given request""
The same data works with tools to send REST requests... so I don't know what I'm missing here...
Can some help?
The error message indicates that the API didn't receive the expected parameters, or at least not in a format it expected. The documentation for /1/oauth2/token say:
Calls to /oauth2/token need to be authenticated using the apps's key and secret. These can either be passed as POST parameters (see parameters below) or via HTTP basic authentication. If basic authentication is used, the app key should be provided as the username, and the app secret should be provided as the password.
You seem to be attempting to supply the parameters as JSON though, according to your Content-Type header. Try sending them as POST parameters instead.

Resources