Javascript AzureAd Consume Rest Service - javascript

RestAPI: I have a Rest API running Asp Core with AzureAd Authentication.
WebApp: I have a separate WebApplication running Asp Core as backend, with Javascript frontend.
The WebApp backend authenticates through AzureAd, and then against the RestAPI to check if a user is registred.
I want the javascript client to be able to consume the Rest API directly. How should i go about this without exposing the accesstoken?
I could go about sending the request from Javascript to WebApp Backend -> Rest API. But i really want to avoid this, because of unnecessary code.

In this scenario, you can try to implement ADAL for js in your JS client. Leveraging **adal** to gain the authentication token, and when you call your Web Api, it will add the authentication header in HTTP requests.
E.G.
Suppose we want to call the Microsoft Graph API from our JS client.we develop a node.js script that uses request to call the Microsoft Graph API for groups to create a new Security Group.
The following code shows how the API is consumed from that script. Note that the token and the name are passed by parameter. Additionally, this function returns a Promise that is successfully resolved when the group is correctly created and rejected when is not.
var request = require('request');
function createGroup(token, name) {
return new Promise((resolve, reject) => {
const options = {
method: 'POST',
url: 'https://graph.microsoft.com/v1.0/groups/',
headers: {
'Authorization': 'Bearer ' + token,
'content-type': 'application/json'
},
body: JSON.stringify({
"displayName": name,
"mailEnabled": false,
"securityEnabled": true
})
};
request(options, (error, response, body) => {
const result = JSON.parse(body);
if (!error && response.statusCode == 204) {
resolve(result.value);
} else {
reject(result);
}
});
});
}
In order to call Microsoft Graph API, we needed to be authenticated and that is why in the previous section we have a token as a parameter of the function which was used to perform the request.
we should add the following code to generate the token. Note that we are using the adal npm package to do this easier, calling the acquireTokenWithClientCredentials method of the AuthenticationContext object. Additionally, we have some constants that need to be updated with the client id and secret obtained before as well as the tenant name.
var adal = require('adal-node');
const TENANT = "{tenant-name-here}.onmicrosoft.com";
const CLIENT_ID = "{Application-id-here}";
const CLIENT_SECRET = "{Application-key-here}";
function getToken() {
return new Promise((resolve, reject) => {
const authContext = new adal.AuthenticationContext(`https://login.microsoftonline.com/${TENANT}`);
authContext.acquireTokenWithClientCredentials(GRAPH_URL, CLIENT_ID, CLIENT_SECRET, (err, tokenRes) => {
if (err) { reject(err); }
resolve(tokenRes.accessToken);
});
});
Hope it helps.

Related

Discord.js: can't fetch user's connections (OAuth2)

I have a Discord app/bot with a custom linked role, and before updating metadata and adding the role, I want to fetch user's connections and look at some data from it.
More specifically, I want to assign a custom role only to users who own a specific game on Steam and have certain achievements from it. Currently stuck at fetching connections part - OAuth in general works fine.
Took this example discord oauth app:
https://github.com/discord/linked-roles-sample
And it works, except for this part: I want to fetch user's connections
Added this new function
export async function getUserConnections(tokens) {
const url = 'https://discord.com/api/v10/oauth2/#me/connections';
const response = await fetch(url, {
method: 'GET',
headers: {
Authorization: `Bearer ${tokens.access_token}`,
},
});
if (response.ok) {
const data = await response.json();
return data;
} else {
throw new Error(`Error fetching user connections: [${response.status}] ${response.statusText}`);
}
}
But this fetch always returns 404, even though scope for connections is defined

Next Js API not posting to an external API

so i was trying to make 2 different projects first one is my ecommerce frontend made with next js and second one is ecommerce dashboard which is also made with next js.
But when i am trying to post products from my dashboard to my ecommerce frontend nothing is happening even also I am not getting any error in console that's why i am unable to understand what is the problem.
Can anyone help me in this ? The fetch code is below.
const handelSubmit = async (e) => {
e.preventDefault();
console.log("clicked");
fetch(`http://192.168.43.53:3000/api/products`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(
name,
price,
// mediaUrl,
description,
collect,
),
})
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.1/umd/react-dom.production.min.js"></script>
Nextjs apis only work with the same origin by default, see Nextjs api Caveats for more info.
If you want to make a fully public api with Nextjs, you have to add cors, see Api Middlewares. Your code will look something like:
import Cors from 'cors'
// Initializing the cors middleware
const cors = Cors({
methods: ['GET', 'HEAD'],
})
// Helper method to wait for a middleware to execute before continuing
// And to throw an error when an error happens in a middleware
function runMiddleware(req, res, fn) {
return new Promise((resolve, reject) => {
fn(req, res, (result) => {
if (result instanceof Error) {
return reject(result)
}
return resolve(result)
})
})
}
If your backend api isn't defined with Nextjs, please share the code of your requested api endpoint and also the technology it uses.
I think the data you are posting needs to be in JSON first.
body: JSON.stringify(
key:value,
key1:value1
)

Clash Royale Node Fetch with Key

Im trying to make a discord bot where if you type -cr into the chat, it takes the Arguments of the user (Being the Clash Royale Player's player tag) and would then use the package node-fetch to receive data with my specified endpoint. I am constantly running into the error of { reason: 'accessDenied', message: 'Invalid authorization' }. Im rather new to this stuff, especially API's, but im hoping to access certain data which I can decide later on (Which I know how to do). My code is :
const fetch = require('node-fetch')
module.exports = {
name: 'clash',
aliases: ['cr', 'clashroyale'],
category: 'This',
utilisation: '{prefix}clash',
async execute(client, message) {
var msgArgs = message.content.slice(this.name.length + 1)
var endpoint = `/players/${msgArgs}`
var url = `https://api.clashroyale.com/v1`
var token = `hidingmytoken`
fetch(url + endpoint, {
method: 'POST',
headers: {
"Authorization": token
}
}).then(data => data.json()).then(json => {
console.log(json)
})
},
};
The message parts with msgArgs and discord sides all work but fetching that clash Royale API is a big hurdle for me. The API for Clash Royale can be found here https://developer.clashroyale.com/#/documentation and Im just generally stuck on this whole concept. Im using version 2.6.6 of node-fetch so I can use the require() method which should work if that does matter. In general, how can I pass my token properly to receive that API data?
Since the Clash Royale API uses bearer authentication, you need to specify that it will be a bearer token.
headers: {
'Authorization': `Bearer ${token}`
}
I've implemented the following functionality. The code is written in GO but you can copy the logic and translate into your language.
The library have the following functionality:
Login
Token generation
Token list
Token delete
https://github.com/alessiosavi/GoClashRoyale/blob/master/api/auth.go

Route that is executed within another route in Node.js is not being executed

Good Evening,
I have a function that contains a route that is a call to the Auth0 API and contains the updated data that was sent from the client. The function runs, but the app.patch() does not seem to run and I am not sure what I am missing.
function updateUser(val) {
app.patch(`https://${process.env.AUTH0_BASE_URL}/api/v2/users/${val.id}`,(res) => {
console.log(val);
res.header('Authorization: Bearer <insert token>)
res.json(val);
})
app.post('/updateuser', (req, ) => {
const val = req.body;
updateUser(val);
})
app.patch() does NOT send an outgoing request to another server. Instead, it registers a listener for incoming PATCH requests. It does not appear from your comments that that is what you want to do.
To send a PATCH request to another server, you need to use a library that is designed for sending http requests. There's a low level library built into the nodejs http module which you could use an http.request() to construct a PATCH request with, but it's generally a lot easier to use a higher level library such as any of them listed here.
My favorite in that list is the got() library, but many in that list are popular and used widely.
Using the got() library, you would send a PATCH request like this:
const got = require('got');
const options = {
headers: {Authorization: `Bearer ${someToken}`},
body: someData
};
const url = `https://${process.env.AUTH0_BASE_URL}/api/v2/users/${val.id}`;
got.patch(url, options).then(result => {
console.log(result);
}).catch(err => {
console.log(err);
});
Note: The PATCH request needs body data (the same that a POST needs body data)

Ionic 2 - How to use refresh token to obtain new JWT

I have an ionic 2 mobile application that uses Json Web Tokens(JWT) to authenticate to various routes on a node.js API. These JWTs have a short expire time, and need to be refreshed using a refresh token. The refresh token is just a random string that is stored both in the database and on the mobile device. Please note: I am NOT using OAuth.
How can I refactor my API calls so that they all go through one method which will send a refresh token if the initial API call gets a 401 Unauthorized response due to an expired JWT? Otherwise, I will need to write the logic for handling that response in every single API call which I would like to avoid.
Here is an example of one method I have implemented in typescript that calls the API. It is not currently handling a 401 Unauthorized response nor is it sending the refresh token yet:
public setBeerPref(beerPrefs) {
return new Promise((resolve, reject) => {
this.storage.get('email').then((email) => {
this.storage.get('token').then((token) => {
beerPrefs["email"] = email;
let headers = new Headers();
headers.append('Authorization', token);
headers.append('Content-Type', 'application/json');
let options = new RequestOptions({ headers: headers });
this.http.post('apiURL', beerPrefs, options)
.subscribe(res => {
let data = res.json();
resolve(data);
resolve(res.json());
}, (err) => {
reject(err);
});
});
});
});
}

Categories