Client must be authenticated to access this resource. jira rest api - node.js

I've created a project using node module passport-atlassian-oauth2 and i get the accessToken successfully. But when I do a request to create an issue I get the error
Client must be authenticated to access this resource.
Below is my code for create issue jira api.
Could you help please?
var bodyData = {
"fields": {
"project": {
"key": "FLUX"
},
"summary": "REST ye merry gentlemen.",
"description": "Creating of an issue using project keys and issue type names using the REST API",
"issuetype": {
"name": "Bug"
}
}
};
var baseUrl = 'https://alamrezoanul.atlassian.net';
var options = {
method: 'POST',
url: `${baseUrl}/rest/api/3/issue`,
data: JSON.stringify(bodyData),
headers: { 'Authorization': 'Bearer ' + jiraTokens.accessToken, 'Content-Type': 'application/json' },
json: true };
axios(options)
.then((response2) => {
console.log("response2.data: ", response2.data);
})
.catch((error) => {
console.log("error: ", error);
})

Hi I encountered the same issue today. You need to fetch the cloud id of https://alamrezoanul.atlassian.net and then instead of doing var baseUrl = 'https://alamrezoanul.atlassian.net'; use var baseUrl = 'https://api.atlassian.com/ex/jira/{cloud id}';.
You can fetch the cloud id by doing a authenticated GET request to https://api.atlassian.com/oauth/token/accessible-resources.

You might want to check the audience in your authorised tokens.
https://developer.atlassian.com/cloud/jira/platform/oauth-2-authorization-code-grants-3lo-for-apps/#implementing-oauth-2-0--3lo-
Setup says:
audience: (required) Set this to api.atlassian.com.
You may need to set to alamrezoanul.atlassian.net

Same issue I have fixed instead username and password use email and api token link to generate token
Below code I am using in my project
public String getEncodedAuth() {
String username = "user#gmail.com";//enter your mail
String auth_header = username + ":" + "<API token>";
String encodedAuth = Base64.getEncoder().encodeToString(auth_header.getBytes());
return encodedAuth;
}
public void getIssue(String issueId) {
Response response = RestAssured.given()
.header("Authorization", "Basic " + getEncodedAuth())
.contentType(ContentType.JSON)
.pathParam("issueIdOrKey", issueId)
.queryParam("fields", "attachment")
.when()
.get("https://user.atlassian.net/rest/agile/1.0/issue/{issueIdOrKey}");
response.prettyPrint();
}

Related

response detail error:2,errMsg:post method api body check failed! Agora REST API

const Authorization = `Basic ${Buffer.from(`${config.CUSTOMERID}:${config.CUSTOMER_SECRET}`).toString("base64")}`;
const acquire = await axios.post(`https://api.agora.io/v1/apps/${config.agoraAppId}/cloud_recording/acquire`,{
cname: groupId,
uid: userId,
clientRequest: {
},
},
{ headers: { Authorization } }
);
Getting the following response when i call agora live streaming cloud recording from nodejs code using axios.
{
code: 2,
reason: 'response detail error:2,errMsg:post method api body check failed!'
}
This means you have been successfully Authorized but you are passing either wrong value or it is not defined in your body or URL.
Please check if any variable you are passing is undefined or contains wrong/incomplete value.
You should pass the header as an object with they Authorization key, in your case:
{
headers: {'Authorization': "Basic " + Authorization}
}

Authorisation in Drchrono

For authorization at DRchrono, I had created a GET request at https://drchrono.com/o/authorize/ with a redirect URL and clientId, as soon as I click on authorize I redirect to my redirect URL with code value in params,
then I made a POST request on https://drchrono.com/o/token/ via postman with this
{
"code":"x4xzqXXjlBWeeQxEzjyE8thFTIW0eT",
"grant_type": "authorization_code",
"redirect_uri": "",
"client_id": " ",
"client_secret": ""
}
client_id and client_secret value taken from DrChrono API management page.
After making a post instead of getting the access token, I get "400 bad requests" in response.
I am not getting what that thing I am missing.
for doing all this thing I followed DRchrono official document :
https://drchrono.com/api-docs/v4?application=4217#section/Authorization/Initial-authorization
Can anyone help me with this??
My issue got resolved by making these 2 changes:
while making the post request we have to pass
Content-Type=application/x-www-form-urlencoded
in header
const Header = {
"Content-Type": "application/x-www-form-urlencoded",
};
we also need to convert our json object into x-www-form-urlencoded, like this:
var postData = {
code:query.code,
grant_type: "authorization_code",
redirect_uri: " ",
client_id: " ",
client_secret: " ",
};
var encodedData = "";
for (key in postData) {
encodedData += encodeURIComponent(key)+"="+encodeURIComponent(postData[key])+"&";
}
and then finally pass Header, encodedData value in post request
request.post("https://drchrono.com/o/token/", (data = encodedData), {
headers: Header,
}) .then((res) => {
console.log("RESPONSE RECEIVED: ", res.data);
})
This article helped me for testing the Authentication from postman: http://drchronoapi.wpengine.com/connecting-to-drchronos-api-via-postman/
Hope this helps to others who faced similar issue :)

Spotify Authorization from Node Server not working with curl

I have a node server which gets an access token from Spotify's Web API. The response looks like this:
Response:
{
"statusCode": 200,
"body": "{\"type\":\"success\",\"done\":{\"json\":{\"access_token\":\"BQDqtYhVpafUIMYtZbwmy6iJcC_wvzR9Xrw6bRDFfpL3zZYfkCp2-KZaQVS-ZoElMF1czAl_B1vEaDrtPBOElSV3D5k\",\"token_type\":\"Bearer\",\"expires_in\":3600,\"scope\":\"user-top-read\"}}}",
"headers": {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": "Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token"
}
}
When I try to use the access_token on Spotify's online API tool, I get an error for incomplete JSON. I think this is because the token I generate is only 91 characters long while the code they generate is 171 characters long. Why is my auth code so short?
I want an access token so I can use this react module for accessing my top tracks.
Here is my code for getting the access token:
let getAccessToken = (queryStringParameters) => {
let url = 'https://accounts.spotify.com/api/token';
let encoded = (new Buffer(client_id + ':' + client_secret).toString('base64'));
console.log("encoded = " + encoded);
let params = {
grant_type: 'authorization_code',
username: username,
password: password,
scope: scope
};
const formParams = Object.keys(params).map((key) => {
return encodeURIComponent(key) + '=' + encodeURIComponent(params[key]);
}).join('&');
return fetch(url, {
method: 'POST',
headers: {
"Authorization": 'Basic ' + encoded,
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded'
},
body: formParams
})
.then((response) => {
console.log(util.inspect(response, { showHidden: true, depth: null }));
return response.json();
})
.catch((error) => {
done({
error: error
});
});
};
According to the Authorisation Guide the authorization_code grant type only takes the code and redirect URI values. Not sure why the username and password ones you provide are even accepted, it is possible the token returned is a client credentials one as those tend to be shorter, that only access non-user related endpoints like loading Artist data, but the parameters you're providing appear to be undocumented at least in that guide.

set-cookie AWS Serverless

Goal: Set a cookie from aws serverless.
I'm using a custom authentication flow
domain: mydomain.com
current domain: dev.mydomain.com
login api (api gateway): account-api.mydomain.com
Login Lambda
the login function is the actual function invoked
This lambda receives a username & password and creates/returns a JWT & cookie string, I've removed non-pertinent logic
*Right now my response contains extra stuff to help me debug/figure out how to map -- I'll be migrating it out once this is successfully setting the cookie
...
const handler = async event => {
const jwtBody = {
email: event.email,
uuid: current_user_info.uuid.S,
zipcode: current_user_info.zipcode.S,
}
var now = new Date();
var time = now.getTime();
var expireTime = time + (milliToHour*24*10);
now.setTime(expireTime);
var jwt = jsonwebtoken.sign(jwtBody, SMCData.secret, { algorithm: SMCData.alg, expiresIn: '1hr'});
const cookieString = "token="+jwt+";expires=" + now.toUTCString() + ";secure;HttpOnly;"
return {
statusCode: 200,
payload: {
verified: current_user_info.verified.BOOL,
jwt: jwt,
cookie: cookieString
}
}
}
const login = middy(handler).use(cors({
origins:[
"https://dev.mydomain.com",
"https://account-api.mydomain.com",
"https://*.mydomain.com"
],
credentials:true
}))
Current Status - postman
post_body = {
"email": "valid_email#email.com",
"password": "correct_password"
}
response_body = {
"statusCode":200,
"payload":{
"verified":false,
"jwt":"eyJh...KAQ",
"cookie":"token=ey...KAQ;expires=Tue, 12 Nov 2019 22:10:32 GMT;secure;HttpOnly;"
}
}
cookie is also set:
Current Status - chrome
Headers:
post_body = {
"email": "valid_email#email.com",
"password": "correct_password"
}
response_body = {
"statusCode":200,
"payload":{
"verified":false,
"jwt":"eyJh...KAQ",
"cookie":"token=ey...KAQ;expires=Tue, 12 Nov 2019 22:10:32 GMT;secure;HttpOnly;"
}
}
cookie is not set:
API Gateway Configuration
CORS is enabled
*I Know I'm 'supposed' to change the mapping value in the integration response into a mapping template, but I wanted to get things working before I figured out how to make that change.
It helps when you setup cors properly in API Gateway. DOH!

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;
});

Resources