Surprisingly I'm getting same code for access_token and id_token - jwt

I have angular app version 6 and I'm trying to integrate Azure AD authentication and the micro services are in AWS.
Surprisingly I'm getting same code for access_token and id_token.
are they supposed to be different? my architect thinks so and asked me to tweak library to send responseType as 'id_token+token'.
What am I doing wrong and is there any way I can get access_token for sending as headers for api calls?
I have also attached the screenshot of the console errors of api c
microsoftadal-api fails
alls.
Below is my piece of code where I was trying to read access token for authenticating api calls.
enter code here
export class AppComponent {
loading: boolean;
constructor(private adalSvc: MsAdalAngular6Service, private router: Router,
private http: HttpClient) {
this.adalSvc.acquireToken('https://api.test.test.com/Dev')
.subscribe((resToken: string) => {
console.log(this.adalSvc.userInfo);
console.log('get resToken -->', resToken);
console.log('get oid -->', this.adalSvc.userInfo.profile.oid);
console.log('get accessToken -->', this.adalSvc.accessToken);
localStorage.setItem('accessToken', this.adalSvc.accessToken);
console.log('get token -->', this.adalSvc[enter image description here][1]
.getToken('https://api.test.test.com/test?userId=111111'));
this.configureRoutes();
this.loading = true;
this.http.get('https://api.test.test.com/test?userId=11111', {
headers: {
'Authorization': 'Bearer ' + this.adalSvc.accessToken,
'userid': this.adalSvc.userInfo.profile.oid,
'username': 'username',
'userrole': 'somerole'
}
}).subscribe(console.log);
this.postCall();
},
error => {
console.log(error);
});
}
postCall() {
const data = {
'dealerId': '111111'
};
const headers = new Headers();
headers.append('Authorization', 'Bearer ' + this.adalSvc.accessToken);
headers.append('userid', this.adalSvc.userInfo.profile.oid);
headers.append('username', 'username');
headers.append('userrole', 'somerole');
return this.http.post(
'https://api.test.test.com/test', data, {
headers: {
'Authorization': 'Bearer ' + this.adalSvc.accessToken,
'userid': this.adalSvc.userInfo.profile.oid,
'username': 'username',
'userrole': 'somerole'
}
}).subscribe((response: Response) => {
console.log(response.json());
});
}
configureRoutes() {
this.router.navigate(['/dealer/home']);
}
}

Make sure that you have specified the right resource.
It's the id_token and not the access_token that you need to send to your backend APIs. Then you can get the access_token from the id_token.
It looks like you might be making the same mistake that the user here made.

Related

Wikidata REST API Forbidden using Access Token?

I have this Node.js request:
/* eslint-disable #typescript-eslint/no-unsafe-member-access */
/* eslint-disable #typescript-eslint/no-unsafe-assignment */
import * as dotenv from 'dotenv'
dotenv.config()
const id = process.argv[2]
download(id)
async function download(id: string) {
// const query = new URLSearchParams({ query: sparql }).toString()
// const url = `https://www.wikidata.org/w/rest.php/wikibase/v0/entities/items/${id}/statements`
// test
const url = `https://www.wikidata.org/w/rest.php/wikibase/v0/entities/items/Q42/statements`
const res = await fetch(url, {
headers: {
Authorization: `Bearer ${process.env.WIKIDATA_ACCESS_TOKEN}`,
'Content-Type': 'application/json',
},
})
console.log(res)
const json = await res.json()
console.log(json)
}
The WIKIDATA_ACCESS_TOKEN is straight from my newly created OAuth client following the REST API docs.
I am getting an error at res.json():
{ error: 'rest-read-denied', httpCode: 403, httpReason: 'Forbidden' }
Why is this not working? I haven't been spamming the system, I just made a couple requests. I checked process.env.WIKIDATA_ACCESS_TOKEN and it does have the correct access token... Is there a step or configuration that I am missing?
Here is the client info.

Is ajax the best/only way to add a jsonwebtoken (JWT) to a request header?

I have a simple multi-page site written in vanilla JS, Pug, and Node, that uses login with JWT. When a user logs in, the client is returned a JWT. The JWT is stored in localStorage. Now, when a user clicks a link to a protected route on a given page, I need to send the JWT to the server so it can authenticate that the JWT is valid (i.e., user is logged in).
I understand I can do something like this for a given protected route:
$.ajax({
url: "/protected",
type: "GET",
headers: {
'Authorization': 'Bearer ' + <token>
}
success: (res) => {
if (res.status == 200) {
window.location.replace("/profile");
}
else {
window.location.replace("/login");
}
},
error: (err) => { console.log(err) }
});
It seems like a lot of overhead for a simple link click. Is this the recommended method of adding a JWT to a request header or is there a better way?
Yes, pretty much this is the only way. But to simplify your things you can create a wrapper on above ajax method and use that function for protected routes.
function authAjax(url, method, successCallback, errorCallback){
$.ajax({
url: url,
type: method,
headers: {
'Authorization': 'Bearer ' + <token>
}
success: (res) => {
if (res.status == 200) {
successCallback(res)
}
else {
window.location.replace("/login");
}
},
error: (err) => {
console.log(err)
errorCallback(err)
}
});
}
And use this like:
authAjax('/protected', 'GET', (data) => {
console.log('API res', data)
}, (err) => {
alert('Sorry, Something went wrong :(')
})

Passport-jwt issue : JWT token is working with postman but not working with UI api call

I have integrated passport-jwt for authentication purpose. It's working like charm but whenever Frontend guy use it from frontend angular 2 its giving Unauthorised 401 . I've tried alot but not getting any clue, it must be a silly mistake though.
my passport strategy file is as
let JwtStrategy = require('passport-jwt').Strategy,
ExtractJwt = require('passport-jwt').ExtractJwt;
//let fromHeader = require('passport-jwt').fromHeader
// load up the user model
const User = require('../components/user/model');
const database = require('./database'); // get db config file
const config = require('./config'); // get db config file
module.exports = function(passport) {
//var passportStrategy = function(passport){
let opts = {};
opts.jwtFromRequest = ExtractJwt.fromAuthHeader();
//opts.jwtFromRequest = ExtractJwt.fromAuthHeaderWithScheme("JWT");
console.log("opts.jwtFromRequest==",opts.jwtFromRequest);
opts.secretOrKey = config.secret;//config.secret;
passport.use(new JwtStrategy(opts, function(jwt_payload, done) {
//console.log("opt==",JSON.stringify(opt));
//console.log("jwt_payload===",jwt_payload);
User.findOne({_id: jwt_payload._doc._id}, function(err, user) {
if (err) {
return done(err, false);
}
if (user) {
done(null, user);
} else {
done(null, false);
}
});
}));
};
my route is as
app.get("/api/user/getAll",
passport.authenticate('jwt',{session:false}),
userController.fetchUsers
);
And frontend header append is as follows :
logoutUser(token) {
//const userData = JSON.stringify(userInfo);
var headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('Authorization', token); //e.g.token = JWT dasddddasdsda
//headers.append('Authentication', token);
console.log(headers)
return this.http.post('http://localhost:9000/api/user/logout', { headers: headers })
.map((response: Response) =〉 {
return response.json()
})
.catch(this.errorHandler);
}
It would really great if anyone can assist me further to identify the mistake.
Second argument for the post method is payload.
so this code below
this.http.post('http://localhost:9000/api/user/logout', { headers: headers })
has to be
this.http.post('http://localhost:9000/api/user/logout', {}, { headers: headers })

Protractor : How to Call Rest API POST with header and body

I have setup steps before running my e2e test in which I have to create users before I execute my test. I am using Protractor's Request API to make REST API POST calls but I'm not sure how can I pass data (body) and headers in the request. My request should look like this:
URL : 'rest/users', Headers : {'Content-Type' : 'application/json'}, body: {"userName": "user1", "domain": "1", "password": "password1", "userID": "1"}
I am trying to do something like this:
var request = require('request');
function createuser(url){
console.log("complete url = ", browser.baseUrl+url);
request({
method: 'POST',
uri: browser.baseUrl+url,
multipart: [
{'Content-Type': 'application/json'},
{body: {
'userName': 'test3',
'tenantKey': '0',
'password': 'Test3',
'userID': '3'}
}
],
function(error, response, body) {
if (error) {
return console.error('User Creation failed:', error);
}
console.log('User Creation successful! Server responded with:', body);
}
})
};
createuser('rest/1.0/dev/users');
It's throwing the following error (I'm not sure what am I doing wrong):
Error: Body attribute missing in multipart.
Stack:
Error: Body attribute missing in multipart.
at C:\code\ui\dgui\node_modules\request\lib\multipart.js:35:36
at Array.forEach (native)
at Multipart.isChunked (C:\code\ui\dgui\node_modules\request\lib\multipart.js:33:11)
at Multipart.onRequest (C:\code\ui\dgui\node_modules\request\lib\multipart.js:104:22)
at Request.multipart (C:\code\ui\dgui\node_modules\request\request.js:1176:19)
at Request.init (C:\code\ui\dgui\node_modules\request\request.js:424:10)
at new Request (C:\code\ui\dgui\node_modules\request\request.js:142:8)
at request (C:\code\ui\dgui\node_modules\request\index.js:55:10)
at createuser (C:\code\ui\dgui\tests\e2e\TestSuites\_BVT\_CreateNewUsers2.js:36:2)
at Suite.<anonymous> (C:\code\ui\dgui\tests\e2e\TestSuites\_BVT\_CreateNewUsers2.js:49:3)
I am able to achieve this using 'superagent', this is how I am using:
CallRestAPI:
var request = require( "superagent" );
var PostUrl = browser.baseUrl + 'rest/1.0/dev/users';
exports.CreateUsers = function(body){
console.log("Executing CreateUsers");
var data = '{' +body + '}';
console.log("Send data in post request = ", data);
request.post( PostUrl ).set('Content-Type', 'application/json').send(data).end(function(err,res){
if(err){
console.log("CreateUsers post error= ", err )
} else{
console.log("CreateUsers post response = ", res.status)
}
});
};
Using this Function as:
var Common = require('../.././helpers/CallRestAPI');
Common.CreateUsers('"userName": "test1", "tenantKey": "0", "password": "Test1", "userID": "1"');
Have managed it in my code with request validation when eg. access token is wrong or app do not respond. Imo it's better approach because your proposition always passes test what can give false positive.
exports.authorize = function (login, pass) {
var action = function () {
return getToken().then(function (token) {
var dfd = protractor.promise.defer();
req.post(getBackendUrl() + '/authorize/authenticate')
.set('Content-Type', 'application/json').set('RequestId', uuid.v4()).set('Authorization', token)
.send({"login": login, "pass": pass})
.end(function (err, res) {
if (err) {
dfd.reject(res)
} else {
dfd.fulfill(res.body);
}
});
return dfd.promise;
})
};
return browser.controlFlow().execute(action);
};
Endpoint authorize returns 200 status code for both - valid and not valid credentials so in specific test it can be distincted by simple jasmine expect like:
var Initialize = require('..initialize');
var successResponse = {status: 'success'};
expect(Initialize.authorize('some_login', 'some_password')).toEqual(successResponse);
var request = require('request');
var options = {
method: 'POST',
url: 'https://sbx-office-api.b2bcloud.com/rmi/v1/books/list?type=fetchall',
headers: {
'Accept': 'application/json, text/plain, */*',
'Authorization': 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IlFrTTFRemt6UlVJNE5UazNSVVJGTUVVNU5rTXlNVVpFT0RJek5EQTNPRFkyTVVaRVFrVXdSZyJ9.eyJodHRwczovL21hcnZlbC5zaGFycC5jb20vdGVuYW50aWQiOiJkNTA4Yjc3NC01NjBlLTRlNTktYTk3Yy1mODQxYjhmYjVkN2QiLCJodHRwczovL21hcnZlbC5zaGFycC5jb20vY29ubmVjdGlvbiI6InNoYXJwc29mdHdhcmVkZXYtd2FhZCIsImh0dHBzOi8vbWFydmVsLnNoYXJwLmNvbS9lbWFpbCI6InJhbWVzaHRAU2hhcnBzb2Z0d2FyZWRldi5vbm1pY3Jvc29mdC5jb20iLCJodHRwczovL21hcnZlbC5zaGFycC5jb20vbmFtZSI6IlJhbWVzaCBUIiwiaHR0cHM6Ly9tYXJ2ZWwuc2hhcnAuY29tL3JvbGUiOiJCQSB1c2VyIiwiaXNzIjoiaHR0cHM6Ly9zYnguYXV0aDAuY29tLyIsInN1YiI6IndhYWR8VGVFbVNzNGpnRGpXeTRVX0ItWlo4SDRobFZielVUdzM4djNmb2MzNXVzWSIsImF1ZCI6WyJodHRwczovL3NieC5hdXRoMC5jb20vYXBpL3YyLyIsImh0dHBzOi8vc2J4LmF1dGgwLmNvbS91c2VyaW5mbyJdLCJpYXQiOjE1NjY5NzY4MzIsImV4cCI6MTU2Njk4NDAzMiwiYXpwIjoiQW1zeU9UbHI3akg5eFU5azZlem15ODJNZDV4NDUyZFIiLCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIn0.D5MoBVJ2lWZ7b3FCZtMQkmdMxJot8SCR1-Oso-wponPtF2y6kLxKK5dUftI_yzydvaJsZ9mwjVvZIAHESlrwkjVizYGXTFchjasT81hMZtJgt6iW8sA7Nu5qx7MVsc2z7UAS0mGhV2a_NEvZaYQ1A0dC19wG2A6bNJIMNEy46oJXlUe8nxb1ezkh4CkO3jUnVIPBo4rney_uwcXj-wc5hiE3a6m7jeHphyy70zDBFD_YRiizZaXzI-LTPGvhuRb7UtfcZuOomQqOuH6xebaoe3OzX9aA7CfWCHIJDhjQJwC-5BR5HQ9k7FCae3L4pWfmUVUOTZEFViJtxazLxOjM_w',
'Content-Type':'application/json',
'Sec-Fetch-Mode': 'cors',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.87 Safari/537.36'
},
body: '{ "headers":{"normalizedNames":{},"lazyUpdate":null}}'
};
it('Should reach testsite', done => {
request(options, function (error, response, body) {
console.log('error:', error);
console.log('statusCode:', response && response.statusCode);
console.log('body:', body);
done();
});
});

Facebook authentication with nodejs

I'm trying to authenticate user in facebook:
var querystring = require('querystring');
var http = require('http');
var fs = require('fs');
getCookies(function(cookies){
logIn(cookies);
});
function logIn(cookies) {
var post_data = querystring.stringify({
'email': 'email#domain',
'pass': 'password'
});
var post_options = {
host: 'www.facebook.com',
port: '80',
path: '/login.php?login_attempt=1',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': post_data.length,
'user-agent': 'Mozilla/5.0',
'set-cookie': cookies[0]
}
};
var post_req = http.request(post_options, function(res) {
res.setEncoding('utf8');
console.log(res.statusCode);
var data = '';
res.on('data', function (chunk) {
data += chunk;
});
res.on('end', function () {
fs.writeFile("C:\\Users\\user\\Desktop\\fb.html", data, function(err) {
if(err) {
console.log(err);
} else {
console.log("The file was saved!");
}
});
});
});
post_req.write(post_data);
post_req.end();
}
function getCookies(callback){
var get_options = {
host: 'www.facebook.com',
port: '80',
path: '/',
method: 'GET',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'user-agent': 'Mozilla/5.0'
}
};
var get_req = http.request(get_options, function(res) {
var cookies = res.headers['set-cookie'];
res.on('end', function (chunk) {
callback(cookies);
});
});
get_req.write('');
get_req.end();
}
But the response is that cookies in my browser are not enabled. Please don't suggest using existing libraries for connecting to facebook, I'm learning... Thanks for help in advance
Facebook uses OAuth authentication to authenticate an user. I have used oAuth module to get access to the Linkedin APIs at http://nabaruns.blogspot.in/2013/01/linkedin-api-call-using-nodejs-oauth.html. You can try the same and see if you can call graph facebook apis.
Hope this helps