Node.js - Get my account details from facebook graph api - node.js

I'm trying to get my facebook account details in node.js via facebook graph api (graph.facebook.com/me?access_token=token), but I can't get it to work with:
access_token = appid + '|' + appsecret
Here is my code:
var https=require('https');
var access_token = process.argv.slice(2)[0] + '|' + process.argv.slice(2)[1];
var options = {
host: 'graph.facebook.com',
path: '/me?access_token=' + access_token
};
https.get(options,function(res){
var data = '';
res.on('data', function (chunk) {
data += chunk;
});
res.on('end', function() {
console.log(data);
});
});
And the error I'm getting:
{"error":{"message":"An active access token must be used to query
information about the current
user.","type":"OAuthException","code":2500}}

Edit:
After reading document again: https://developers.facebook.com/docs/facebook-login/access-tokens.
I realize facebook has 4 types of token:
User Access Token
App Access Token = app_id|app_secret
Page Access Token
Client Token
App Access Token is used to read the app settings (not the user info).
And "https://graph.facebook.com/me" is for user info so we need to use User Access Token
example of using app access token:
https://graph.facebook.com/APP_ID/roles?&access_token=APP_ID|APP_SECRET

I was missing the &grant_type=client_credentials in the url:
To Get the app Access Token for facebook api.
But the app token isn't the one with which you get information about your user, in this case I need the user access token which I can get from Graph Api Explorer

Related

How to collect Instagram App Secret to generate a long-lived token?

On this page I generate the access token and with it I can publish the image on my Instagram:
For publish:
function InstagramPost() {
const access_token = 'GENERATE ACESS TOKEN';
const instagram_business_account = 'YYYYYYYYYYYYYYYYYY';
const image = 'https://upload.wikimedia.org/wikipedia/en/9/95/Test_image.jpg';
const text = 'Hello World';
var formData = {
'image_url': image,
'caption': text,
'access_token': access_token
};
var options = {
'method' : 'post',
'payload' : formData
};
const container = 'https://graph.facebook.com/v14.0/' + instagram_business_account + '/media';
const response = UrlFetchApp.fetch(container, options);
const creation = response.getContentText();
var data = JSON.parse(creation);
var creationId = data.id
var formDataPublish = {
'creation_id': creationId,
'access_token': access_token
};
var optionsPublish = {
'method' : 'post',
'payload' : formDataPublish
};
const sendinstagram = 'https://graph.facebook.com/v14.0/' + instagram_business_account + '/media_publish';
UrlFetchApp.fetch(sendinstagram, optionsPublish);
}
Now I want to take this access token and generate a long-lived one with it!
It asks for Instagram App Secret, but that path indicated (App Dashboard > Products > Instagram > Basic Display > Instagram App Secret) doesn't exist in App Dashboard!
I tried using the App secret as a parameter:
"https://graph.instagram.com/access_token
?grant_type=ig_exchange_token
&client_secret={App Secret Key}
&access_token={short-lived-access-token}"
But this error occurs:
Sorry, this content isn't available right now
The Facebook API is 100% accessible, so that's not the problem.
In Javascript/NodeJS I couldn't get it working at all (also on PostMan), I was using the request library.
Changed my code to:
const respLong = await axios.get(`https://graph.instagram.com/access_token?grant_type=ig_exchange_token&client_secret=${CLIENT_SECRET}&access_token=${accessTokenShort.toString()}`);
And magically this works. I can't tell you why what seems to be the exact same request in Postman and the request library doesn't work.
See pic of the url to get app secret (add your app ID) is: https://developers.facebook.com/apps/YOUR_APP_ID(number)/instagram-basic-display/basic-display/
There is a difference in approach between Basic Display and Instagram Graph API for Business Account.
So the way to convert a short-lived token to a long-lived token for Instagram Business Account is:
"https://graph.facebook.com/{graph-api-version}/oauth/access_token?
grant_type=fb_exchange_token&
client_id={app-id}&
client_secret={app-secret}&
fb_exchange_token={your-short-lived-access-token}"
Note that Instagram App Secret is not used, instead, use App Id and App Secret.

Endpoint to fetch Subreddits of a Reddit Account

I have completed the oauth flow for my third party app against a Reddit account and I've gotten the access token for the account.
Now my next issue is
How can I fetch the subreddits for an account using the access token
I can't seem to figure out the endpoint for that.
Does anyone know the endpoint for that?
Thank you
The Reddit OAuth Docs say that for the /subreddits/mine/(where) endpoint, the subreddits OAuth scope is necessary.
Once that scope is acquired for a user, you can use the following snippets of code to access the list of subscribed subreddits for the user:
View a users subreddits                                                                                
View in Fusebit
// Demonstrate using snooclient and Fusebit
const subscriptions = await redditClient.getSubscriptions().fetchAll();
// OR fetch the first page using a raw HTTP request
// - the User-Agent is necessary, don't forget it!
const access_token = redditClient.fusebit.credentials.access_token;
const httpSubs = await superagent.get(
'https://oauth.reddit.com/subreddits/mine/subscriber')
.set('Authorization', `Bearer ${access_token}`)
.set('User-Agent', 'Fusebit Integration');
const length = httpSubs.body.data.children.length;
ctx.body = {
usingSnoo: `User has ${subscriptions.length} subreddits`,
usingHttp: `The first page has ${length} subreddits`,
};
});

Access to User Outlook Calendar from REST API

I'm struggling a bit with Microsoft authentication architecture to access resources using the Graph API.
Let me explain my use-case: I have an Outlook account, which I need to insert events into the Calendar. I also have a REST API, in Node.js, that should read these events, using /me/events or /users/{id}/events Graph endpoint.
Since it is only one user, I don't need to implement login, but rather have the REST API be able to get an Authorization token to access these resources.
I tried to use the ConfidentialClientApplication class to login using the client_id and client_secret for my application (configured through Azure), but whenever I call the Microsoft Graph after login, I receive a 401.
Assuming that the problem is that the login I'm performing is with an admin account, I added the Application type Calendars.Read permission, to no help.
What am I doing wrong?
I just need to access this users' Calendar :(
Thanks for making it this far!
If you want to use ConfidentialClientApplication to get an access token and call Microsoft Graph API to read users' Calendar, try the code below :
const msal = require('#azure/msal-node');
const fetch = require('node-fetch');
const tenant= '<your tenant ID/name>'
const appID= '<azure ad app id>'
const appSec = '<azure ad app sec>'
const userID = '<user ID/UPN>'
const config = {
auth: {
clientId: appID,
authority: "https://login.microsoftonline.com/" + tenant,
clientSecret: appSec
}
}
function readUserCalendar(userID,accessToken){
const URL = 'https://graph.microsoft.com/v1.0/users/'+userID+'/events?$select=subject'
fetch(URL,{headers: { 'Authorization': 'Bearer ' + accessToken}})
.then(res => res.json())
.then(json => console.log(json));
}
const pca = new msal.ConfidentialClientApplication(config);
const acquireAccessToken = pca.acquireTokenByClientCredential({
scopes: ["https://graph.microsoft.com/.default"]
});
acquireAccessToken.then(result=>{readUserCalendar(userID,result.accessToken)})
Permissions grand to azure ad app in this case :
My test account calendar data:
Result :

Azure ADAL - How to get refresh token / how to refresh access token for nodejs backend server to server connection?

I'm using adal-node module for my Node JS backend to write file to Azure Storage. The authentication works fine, but the access token I got only valid for 1 hour. And so far I couldn't find anyway to refresh my access token. Can someone advise?
I've tried to get refresh token. But the auth function I'm using below don't send refresh token back. I've also try to just create a new token after a while using the same auth function, but it turns out the token is always the same.
Here's the code I use to get the access token.
var AuthenticationContext = require('adal-node').AuthenticationContext;
var authorityHostUrl = 'https://login.windows.net';
var tenant = 'myTenant.onmicrosoft.com'; // AAD Tenant name.
var authorityUrl = authorityHostUrl + '/' + tenant;
var applicationId = 'yourApplicationIdHere'; // Application Id of app registered under AAD.
var clientSecret = 'yourAADIssuedClientSecretHere'; // Secret generated for app. Read this environment variable.
var resource = '00000002-0000-0000-c000-000000000000'; // URI that identifies the resource for which the token is valid.
var context = new AuthenticationContext(authorityUrl);
context.acquireTokenWithClientCredentials(resource, applicationId, clientSecret, function(err, tokenResponse) {
if (err) {
console.log('well that didn\'t work: ' + err.stack);
} else {
console.log(tokenResponse);
}
});
Need some way to refresh my access token so that my long running job wouldn't stop.
Just get a new access token.
In the Client Credentials flow, a refresh token is not returned. (See Section 4.4.3 of the OAuth 2.0 spec.)

Accessing Function App via App Service Authentication from Dynamics 365 Plugin

I am trying to access an Azure Function from Dynamics 365 Plugin via service to service call: https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-protocols-oauth-service-to-service
This function is protected via App Service Authentication.
I created a Function App and enabled App Service Authentication
under Platform Features -> Authentication/Authorisation.
I enabled Azure Active Directory as the Auth Provider and set Management mode to Express
I then got the generated Client ID and Client Secret from the Advanced Mode:
Apparently this is all that is needed to make a token request for the Azure function based, based on article I need 4 required parameters:
Client ID
Client Secret
Grant Type
Resource
I make the following request to generate a token from a Dynamics 365 Plugin but get the following error:
Invalid Plugin Execution Exception: Microsoft.Xrm.Sdk.InvalidPluginExecutionException: {"error":"invalid_client","error_description":"AADSTS70002: Error validating credentials. AADSTS50012: Invalid client secret is provided.\r\nTrace ID: 06ddda7f-2996-4c9b-ab7e-b685ee933700\r\nCorrelation ID: d582e2f2-91eb-4595-b44b-e95f42f2f071\r\nTimestamp: 2018-05-23 06:30:58Z","error_codes":[70002,50012],"timestamp":"2018-05-23 06:30:58Z","trace_id":"06ddda7f-2996-4c9b-ab7e-b685ee933700","correlation_id":"d582e2f2-91eb-4595-b44b-e95f42f2f071"}-The remote server returned an error: (401) Unauthorized.
My code is :
var tokenendpoint = "https://login.microsoftonline.com/de194c13-5ff7-4085-91c3-ac06fb869f28/oauth2/token";
var reqstring = "client_id=" + Uri.EscapeDataString("5f315431-e4da-4f68-be77-4e257b1b9295");
reqstring += "&client_secret=" + Uri.EscapeDataString("/oK7nh8pl+LImBxjm+L7WsQdyILErysOdjpzvA9g9JA=");
reqstring += "&resource=" + Uri.EscapeUriString("https://keyvaultaccess.azurewebsites.net");
reqstring += "&grant_type=client_credentials";
//Token request
WebRequest req = WebRequest.Create(tokenendpoint);
req.ContentType = "application/x-www-form-urlencoded";
req.Method = "POST";
byte[] bytes = System.Text.Encoding.ASCII.GetBytes(reqstring);
req.ContentLength = bytes.Length;
System.IO.Stream os = req.GetRequestStream();
os.Write(bytes, 0, bytes.Length);
os.Close();
//Token response
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
StreamReader tokenreader = new StreamReader(resp.GetResponseStream());
string responseBody = tokenreader.ReadToEnd();
I have made sure that I have the correct Client Secret and have also encoded it as I have read somewhere that '+' and '/' are no good.
I am getting the same error in Postman
Any ideas??
reqstring += "&resource=" + Uri.EscapeUriString("https://keyvaultaccess.azurewebsites.net");
Since you set resource parameter to https://keyvaultaccess.azurewebsites.net, I assumed that you have set the App ID URI of your AAD app (clientId equals 5f315431-xxxxxxx-4e257b1b9295) to https://keyvaultaccess.azurewebsites.net. I assume that you could retrieve the access_token, but when accessing your azure function endpoint with the access_token, you got the 401 status code.
You need to modify your advanced management mode for Active Directory Authentication, add https://keyvaultaccess.azurewebsites.net to ALLOWED TOKEN AUDIENCES or change the resource parameter to your AAD clientID when sending the token request for acquiring the access_token.
Active Directory Authentication configuration:
TEST:
Docode the JWT token to check the aud property:
Access my Azure Function endpoint:
Note: You need to take care of the Authorization level of your function as follows:
If you also enable function level authentication, your request sent to azure function needs to have the relevant code parameter in the querystring or set the header x-functions-key with the value of your function key, or you may just set the authorization level to Anonymous.

Resources