Getting access token for Auth0 with Express - node.js

in my Express app I have to get access token for Auth0. In the documentation, they have an example for pure Node JS with a request:
var request = require("request");
var options = { method: 'POST',
url: 'https://XXX.eu.auth0.com/oauth/token',
headers: { 'content-type': 'application/json' },
body: '{"client_id":"XXX","client_secret":"XXX","audience":"http://localhost:3001/","grant_type":"client_credentials"}' };
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
But when I'm trying to do the same in a next way:
app.post('/token', function(options, res) {
return res.json()
});
I'm getting "UnauthorizedError: No authorization token was found".
How can I do it properly?

Are you sure that you have enabled client_credentials grant type in your app?
Go to application / advanced / grant types and enable client_credentials
See picture here

Related

In Node.js, why doesn't the request package perform basic authentication?

I have set up a test end point here:
https://9wi46s5jzc.execute-api.us-east-1.amazonaws.com/test
For some baseline testing, I go to apitester.com and run two tests:
Firstly, a post request to: https://admin:password#9wi46s5jzc.execute-api.us-east-1.amazonaws.com/test (correct credentials) gives me output of:
{"isBase64Encoded":false,"statusCode":401,"headers":{"x-powered-by":"Express","content-type":"text/html; charset=utf-8","content-length":"0","etag":"W/\"0-2jmj7l5rSw0yVb/vlWAYkK/YBwk\""},"body":""}
Secondly, a post request to: https://admin:BADPASSWORD#9wi46s5jzc.execute-api.us-east-1.amazonaws.com/test (incorrect credentials) gives me output of:
{"message":"Unauthorized"}
So they're the baseline tests for what should happen.
When I run the following code:
const request = require('request');
const url = 'https://admin:password#9wi46s5jzc.execute-api.us-east-1.amazonaws.com/test';
request.post(url, function(err, res, body) {
console.log("body", body);
});
I get:
body {"message":"Unauthorized"}
Why is this happening?
According to the docs:
https://github.com/request/request
this is the way to do basic authentication.
So I'm expecting correct authorization but I'm not getting it. What am I doing wrong?
You should try it using this :
const proxyUrl = 'https://admin:password#9wi46s5jzc.execute-api.us-east-1.amazonaws.com/test';
const proxyRequest = request.defaults({ 'proxy': proxyUrl});
const options = {
url: '...',
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"Authorization": "Bearer " + token // if this is how you handle auth and you already have the token
}
};
proxyRequest .get(options, function (error, response, body) {
if (error) {
next(error); // if you're using Express
}
console.log("body", body);
});

How to access form submissions from Netlify for logged in users (with certain roles) only

I have a question about getting form submissions, but only for registered users with a certain role in my application.
My first failed attempt:
I have tried to create a lambda function which accesses form submissions using the access_token received from a succesfull (invite-user) login on my client. However, I am only getting an empty response.
My second attempt:
Instead of using the user's access_token, I created a new Personal access token, stored it as an environment variable in my application on Netlify, and I use the token in my lambda function using process.env.ACCESS_TOKEN. Using this approach is valid, and I received all form submissions.
Here is my lambda function, test.js:
const request = require('request');
exports.handler = function(event, context, callback) {
let ACCESS_TOKEN = process.env.ACCESS_TOKEN; // when using my personal API token created in Netlify. Does work
let ACCESS_TOKEN = event["queryStringParameters"]['access_token']; // passing the user's `access_token` from the client in request url. Does not work.
const options={
url: "https://api.netlify.com/api/v1/sites/MY_SITE_ID/forms/MY_FORM_ID/submissions",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${ACCESS_TOKEN}`
}
}
request(options, (error, response, body) => {
console.log("access_token", ACCESS_TOKEN); // I know the ACCESS_TOKEN is present in both of my scenarios.
callback(null, {
headers: { "Access-Control-Allow-Origin": "http://localhost:4200","Access-Control-Allow-Headers": "Content-Type"},
statusCode: 200,
body: body
});
});
}
My request url from the client looks like this:
https://MY_DOMAIN.com/.netlify/functions/test?access_token=ACCESS_TOKEN.
I am wondering how I can get form submissions for users with certain roles only. What am I doing wrong? What is the best practice for my scenario?
I sent my question to the team at Netlify, and they were able to help me out. It seems that the acces_token I was sending to the lamdba function was a JWT (json web token). All I needed to do was to decode and verify the JWT in order to access my data. I could then use the user object decoded from the JWT to read the roles. I ended up using code similar to this:
const request = require('request');
const jwt = require('jsonwebtoken');
exports.handler = function(event, context, callback) {
const JWT_SECRET = "MY SECRET"; // secret used to verify the signature of the jwt
let ACCESS_TOKEN;
let user;
if (event && event.queryStringParameters && event.queryStringParameters.access_token) {
const jwt_token = event.queryStringParameters.access_token;
jwt.verify(jwt_token, JWT_SECRET,
(err, decoded) => {
user = decoded;
});
}
if(user && user.app_metadata && user.app_metadata.roles &&
(user.app_metadata.roles.includes("admin") || user.app_metadata.roles.includes("editor"))){
if(process.env && process.env.ACCESS_TOKEN){
ACCESS_TOKEN = process.env.ACCESS_TOKEN;
}
}
const options={
url: "https://api.netlify.com/api/v1/sites/SITE_ID/forms/FORM_ID/submissions",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${ACCESS_TOKEN}`
}
};
request(options, (error, response, body) => {
callback(null, {
headers: { "Access-Control-Allow-Origin": "http://localhost:4200","Access-Control-Allow-Headers": "Content-Type"},
statusCode: 200,
body: body
});
});
}

How to get Microsoft Graph API Access token from Node Script?

I'd like to use this library to interact with the graph API for my AD - https://github.com/microsoftgraph/microsoft-graph-docs/blob/master/concepts/nodejs.md
However, all of the existing javascript libraries I've found to return access tokens expect a return URL to be passed in, as well as some other web-specific stuff, leading me to believe this is some kind of requirement on Microsoft's end.
Is there any good way to authenticate/receive an access token while running a backend node script (nothing web related) so that I can begin to make calls against the Microsoft Graph API? Thanks in advance for the advice.
BU0's answer didn't work correctly for me because Microsoft changed their way of using the graph API so I wasn't able to get all the data I needed. Here's how I did it using BU0 answer and this tutorial:
const request = require("request");
const endpoint = "https://login.microsoftonline.com/[Tenant]/oauth2/v2.0/token";
const requestParams = {
grant_type: "client_credentials",
client_id: "[ApplicationID]",
client_secret: "[Key]",
scope: "https://graph.microsoft.com/.default"
};
request.post({ url: endpoint, form: requestParams }, function (err, response, body) {
if (err) {
console.log("error");
}
else {
console.log("Body=" + body);
let parsedBody = JSON.parse(body);
if (parsedBody.error_description) {
console.log("Error=" + parsedBody.error_description);
}
else {
console.log("Access Token=" + parsedBody.access_token);
}
}
});
function testGraphAPI(accessToken) {
request.get({
url:"https://graph.microsoft.com/v1.0/users",
headers: {
"Authorization": "Bearer " + accessToken
}
}, function(err, response, body) {
console.log(body);
});
}
To run a back-end non-user-authenticated daemon connected to the Graph API, you want to use the app-only authentication flow. Here's a quick summary of the official steps:
Create your Azure AD Tenant. Note the yourtenant.onmicrosoft.com name, and copy this value down.
Register an application through the global Azure Active Directory blade's App Registrations section, not directly within the tenant properties. Copy the Application ID; we'll need it later.
Create a key tied to the registration and remember to copy it down. Once you click out, you can't get the key value back, so make sure to copy it.
Also update the registration's permissions to what you need, click Save, and then also hit the Grant Permissions button.
Make an HTTP request to the login.microsoftonline.com domain to obtain an access token.
Use the access token to make Graph API requests.
Here's a link to Microsofts Node.js example, and here's a link to the direct documentation on the HTTP call to make to retrieve an access token. And here's a super stripped-down example that will output the retrieved access token. Replace the [Tenant], [ApplicationID], and [Key] values:
const request = require("request");
const endpoint = "https://login.microsoftonline.com/[Tenant].onmicrosoft.com/oauth2/token";
const requestParams = {
grant_type: "client_credentials",
client_id: "[ApplicationID]",
client_secret: "[Key]",
resource: "https://graph.windows.net"
};
request.post({ url:endpoint, form: requestParams }, function (err, response, body) {
if (err) {
console.log("error");
}
else {
console.log("Body=" + body);
let parsedBody = JSON.parse(body);
if (parsedBody.error_description) {
console.log("Error=" + parsedBody.error_description);
}
else {
console.log("Access Token=" + parsedBody.access_token);
}
}
});
Once we have the access_token, we can call out to the Graph API. Assuming the apps permissions were configured correctly and applied from step #4, we can start making Graph API requests:
function testGraphAPI(accessToken) {
request.get({
url:"https://graph.windows.net/[Tenant]/users?api-version=1.6",
headers: {
"Authorization": accessToken
}
}, function(err, response, body) {
console.log(body);
});
}
I had somewhat of an issue for using the url string for the const endpoint
https://login.microsoftonline.com/[Tenant]/oauth2/v2.0/token
Instead, I passed tenant in this way instead from Microsoft graph api docs:
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize
Reference from docs -> Request an authorization code
Another way:
'use strict';
const axios = require('axios');
const qs = require('qs');
const accessTokenWithCredentials = (tenantId, clientId, clientSecret, resource) => {
const data = {
resource: resource,
grant_type: 'client_credentials',
};
return axios({
url: `https://login.windows.net/${tenantId}/oauth2/token`,
method: "post",
headers: { 'content-type': 'application/x-www-form-urlencoded' },
auth: {
username: clientId,
password: clientSecret,
},
data: qs.stringify(data)
}).catch(error => {
throw error;
})
};
To call the function:
accessTokenWithCredentials(<tenantId>, <clientId>, <clientSecret>, 'https://graph.microsoft.com').then(response => {
console.log(`Got access token`);
const token = JSON.stringify(response.data.access_token);
// do what you need to do
}).catch(err => {
console.log("err " + err);
throw err;
});

OAuth2 using Curl/Node.js is not giving any response

I'm able to sucessfully create the Access token using postman with following parameters,
Callback URL: https://www.getpostman.com/oauth2/callback
Token Name:
Auth URL:
Access Token URL:
Client ID:
Client Secret:
Grant Type:Client Credentials.
But I could not able to get the access token via Curl or node.js as below,
var request = require("request");
var options = { method: 'POST',
url: '',
headers: { 'content-type': 'application/json' },
body: '{"client_id":"","client_secret":"","audience":","grant_type":"client_credentials"}' };
request(options, function (error, response, body) {
if (error) console.log(error);
//console.log(response);
console.log(body);
});
where I mapped my postman details to node.js script as,
Auth URL: url
Access Token URL: audience
Client Id: client_id
Client Secret: client_secret
Grant Type: grant_type
But I didn't any response. May I Know where i went wrong? or do we have any other mechanism to get the OAuth2 access token?
I'm just followed the script from https://manage.auth0.com/#/apis/590983763e3ae44a0dd1a219/test
After few research, I myself found the solution to generate the OAuth2 token through the code using the request, and I mapped by Postman values into the request_options as,
const options = {
url: access_token_url,
method: 'POST',
auth: {
user: client_id,
pass: client_secret,
},
form: {
grant_type: grant_type,
},
};
and used the request method to get the access token by,
request(options, (error, response, body) => {
if (error) return reject(error);
return resolve(body);
});
This helps me to generate the OAuth2 access token inside my script and fixed my requirement.

Google Cloud Print API: User credentials required

I'm trying to use the Google Cloud Print library to get a list of the cloud printers available to the users, but when I do a request I get an error: "User credentials required"
This is how I send the request:
var request = require('request');
var options = {
url: 'https://www.google.com/cloudprint/search',
headers: {
'X-CloudPrint-Proxy': 'APP_NAME',
'Authorization': 'GoogleLogin auth=ACCESS_TOKEN_HERE'
}
};
function callback(err, response, body) {
console.log(err);
console.log(response);
console.log(body);
}
request(options, callback);
In order to make this work (as there is no exact documentation).
Add https://www.googleapis.com/auth/cloudprint to the scope of the login procedure.
If you look here: https://github.com/dpsm/android-print/blob/master/src/main/java/com/github/dpsm/android/print/GoogleCloudPrint.java
They want the Authorization to be
Bearer ACCESS_TOKEN_HERE
instead of
GoogleLogin auth=ACCESS_TOKEN_HERE

Resources