What is wrong with this HTTP-Get Basic authentication code? - javascript

I am using node.js restify as backend to run a REST API server and angularjs as front-end to call the HTTP GET. The REST server uses HTTP Basic Authentication. The username is foo and password is bar.
I have tested that the backend code works by using a restify client. Here is the working client code;
var client = restify.createJsonClient({
url: 'http://127.0.0.1'
});
client.basicAuth('foo', 'bar');
client.get('/alert?list=alertList', function(err, req, res, obj) {
console.log(obj);
});
I have trouble getting my angularjs http-get code to work. Here is the relevant code;
.controller('ViewCtrl', ['$scope', '$http', '$base64',
function ($scope, $http, $cookies, $base64) {
var url = '127.0.0.1/alert?list=alertList';
var auth = $base64.encode('foo:bar');
$http.defaults.headers.common['Authorization'] = 'Basic ' + auth;
$http.get(url).then(function (response) {
tableData = response.data;
//handle data
});
}
I cannot figure out what is wrong with the angularjs code. I am using restify authorizationParser. Are there any extra header requirements to get HTTP basic authentication working with restify authorizationParser?
The error message on the browser looks like this;
{
code: "NotAuthorized",
message: ""
}
In the chrome debugger, this is what I see;
Request Method:GET
Status Code:403 Forbidden
Remote Address:127.0.0.1:80
Request Headers
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8,zh-CN;q=0.6,zh;q=0.4,zh-TW;q=0.2,ja;q=0.2
Cache-Control:max-age=0
Connection:keep-alive
Host:127.0.0.1
If-Modified-Since:Wed, 23 Dec 2015 02:22:04 GMT
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36
I am using this base64 angular module.
https://github.com/ninjatronic/angular-base64
EDIT: I discovered there is nothing with the angular code. The problem lies with the restify server. The restify server supports static web server and when http basic authentication was enabled, this static web server stopped working.

Inside the controller, you can pass the authentication header like this:
var url = '127.0.0.1/alert?list=alertList';
var auth = $base64.encode('foo:bar');
var headers = {"Authorization": "Basic " + auth};
$http.get(url, {headers: headers}).then(function (response)
tableData = response.data;
//handle data
});

Related

Receiving JSON between local React App and local Springboot service issues

I am running a local Springboot server, that when I access it locally in the browser, gives me a valid JSON object properly formatted (I verified this via JSON formatter).
I am also locally running a React application using node. I am attempting to use fetch() to get back that JSON object and running into issues. Finally got around CORs header issues, but not cannot figure out why the JSON object isn't coming back. Here's my code
var headers = new Headers();
headers.append("Content-type", "application/json;charset=UTF-8");
var myInit = { method: 'GET',
headers: headers,
mode: 'no-cors',
cache: 'default',
};
fetch(`http://localhost:3010/getJSON`, myInit)
.then(function(response){
console.log(response.data);
console.log(response);
console.log(JSON.parse(JSON.stringify(response)));
},function(error){
console.log(error);
});
So when I run this in Chrome with the debugger, the responses to the 3 log statements are:
1st logger
undefined
2nd logger
Response {type: "opaque", url: "", redirected: false, status: 0, ok: false,
…}
body
:
(...)
bodyUsed
:
false
headers
:
Headers {}
ok
:
false
redirected
:
false
status
:
0
statusText
:
""
type
:
"opaque"
url
:
""
__proto__
:
Response
3rd logger
{}
I have tried many different JSON parsing, stringify, etc, to no avail.
The next confusing part, is if within the Chrome debugger I go to the "Network" tab, click on the /getJSON, it shows me the entire JSON object just fine in both the "Preview" and "Response" tabs. So clearly Chrome is connecting to it correctly. Here's Chrome's "Headers" tab within "Network":
Request URL:http://localhost:3010/getJSON
Request Method:GET
Status Code:200
Remote Address:[::1]:3010
Referrer Policy:no-referrer-when-downgrade
Response Headers
view source
Content-Type:application/json;charset=UTF-8
Date:Thu, 12 Oct 2017 16:05:05 GMT
Transfer-Encoding:chunked
Request Headers
view source
Accept:*/*
Accept-Encoding:gzip, deflate, br
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Host:localhost:3010
Referer:http://localhost:3000/
User-Agent:Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36
I have tried to mimic this header in my request, but not sure how it differs? Any help would be greatly appreciated as I am currently banging my head against the way with this!
You're getting an opaque response, which tells me that maybe you haven't completely resolved the cors headers situation. If you're fetching from the client, I would suggest proxying that through your nodejs so that instead of calling your springboot service, you call node, thus getting rid of the cors issues.
EDIT
You could create something like this:
import express from 'express';
import request from 'request';
const router = express.Router();
router.get('/proxyname', (req, res) => {
// Removing IPv4-mapped IPv6 address format, if present
const requestUrl = [your service's endpoint];
request(requestUrl, (err, apiResponse, body) => {
res.status(apiResponse.statusCode);
try {
res.json(JSON.parse(body));
} catch (e) {
res.send(body);
}
});
});
export default router;
and then on your nodejs server file, add it, like this:
import proxy from '[path to proxy file above]';
app.use('/path-to-endpoint', proxy);
and then call that from the client instead of your SpringBoot service.

AWS API Gateway UnrecognizedClientException with Generated Javascript SDK

I'm encountering a 403 status code with an UnrecognizedClientException in the x-amzn-errortype header of the response to my API Gateway GET Request using the generated Javascript SDK. The Resource being called utilizes IAM Auth which differentiates the users role based on their user group.
Here is my API Client Initialize Function
function initializeAPIClient(accessKey, secretKey, sessionToken){
var config = {
region : region,
accessKey : accessKey,
secretKey : secretKey,
sessionToken : sessionToken
}
apigClient = apigClientFactory.newClient(config);
}
Here is my GET request Function
function testCall(){
var params = '';
var body = '';
var additionalParams = '';
apigClient.testCallGet(params, body, additionalParams)
.then(function(result){
alert("Permissions are available to this user.");
})
.catch(function(result){
alert("Permissions are NOT available to this user.");
});
}
Here are my request headers:
:authority:[API_ENDPOINT]
:method:GET
:path:/[STAGE]/[RESOURCE]
:scheme:https
accept:application/json
accept-encoding:gzip, deflate, sdch, br
accept-language:en-US,en;q=0.8
authorization:AWS4-HMAC-SHA256 Credential=[ACCESS_KEY_ID]/20170406/[REGION]/execute-api/aws4_request, SignedHeaders=accept;host;x-amz-date, Signature=[SIGNATURE]
origin:http://localhost:8000
referer:http://localhost:8000/php/[PAGE].php/?username=[USERNAME]&sessionToken=[SESSION_TOKEN]
user-agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36
x-amz-date:20170406T180808Z
x-amz-security-token:[SESSION_TOKEN]
I'm not sure what could be causing this. The solutions recommended when I search UnrecognizedClientException seem to suggest doing what I'm already doing.
I've solved my own issue, so here's the answer for anybody who runs into a similar logic error. Do NOT use the Id token as your session token, which is what I was doing. The id token is used to generate the session token, along with the access key and secret key. Do not confuse the two.

How can I send a big file from the browser to the Node.js server?

I'm trying to send from the client to the server an image using data: URL. My functions to read the uploaded image and send data to the server are very simple:
getTags = event => {
const file = event.target.files[0];
if (!file.type.match('image.*')) {
return;
}
const reader = new FileReader();
reader.onload = (theFile => {
return (e) => {
this.sendDataToServer(e.target.result, theFile.type);
};
})(file);
reader.readAsDataURL(file);
}
sendDataToServer = (data, fileType) => {
const options = {
method: 'POST',
headers: {
'Content-Type': fileType,
},
body: JSON.stringify({data}),
cache: 'default'
}
fetch('http://localhost:5000/img', options)
.then(res => res.text())
.then(body => {
console.log(body);
});
}
If I print e.target.result before put it into sendDataToServer I see a valid data: URL.
So, my server:
const app = express();
app.use(cors());
app.use(helmet());
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
app.post('/img', (req, res, next) => {
const data = decodeURIComponent(req.body.data);
console.log(data);
// ...
But in Chrome DevTools in Network tab, I see:
Request URL:http://localhost:5000/img
Request Method:OPTIONS
Status Code:204 No Content
Remote Address:52.15.183.149:80
Response Headers
view source
Access-Control-Allow-Headers:content-type
Access-Control-Allow-Methods:GET,HEAD,PUT,PATCH,POST,DELETE
Access-Control-Allow-Origin:*
Date:Sat, 25 Mar 2017 20:18:09 GMT
X-Powered-By:Express
Request Headers
view source
Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-GB,en-US;q=0.8,en;q=0.6
Access-Control-Request-Headers:content-type
Access-Control-Request-Method:POST
Connection:keep-alive
DNT:1
Host:b580f823.ngrok.io
Origin:http://localhost:3000
Referer:http://localhost:3000/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36 OPR/43.0.2442.1165
On the server my console.log just print undefined. Can't understand why it's happened. Where is my mistake?
Everything in the question showing the client-side info indicates it’s working OK from the client side.
So it seems like there must be some problem on the server side not caused by any client error.
I say that because:
The devtools snippet for the request shows Request Method:OPTIONS, which is expected since your POST has a Content-Type header other than application/x-www-form-urlencoded,
multipart/form-data,
or text/plain.
In that case, your browser first sends a CORS preflight OPTIONS request and expects to get back a Access-Control-Allow-Headers:content-type response header along with an Access-Control-Allow-Methods including POST, and Access-Control-Allow-Origin.
The devtools snippet in the question shows it gets all those as expected, so it should then be sending the actual POST. You don’t show a devtools snippet for that POST but if your browser were not doing the actual POST it would be logging some kind of error to the devtools console.
So unless I’m missing something, there are no mistakes in your client-side code, thus there instead must be some problem on the server side that’s causing it to fail.

Custom Headers added in AngularJS only show on Access-Control-Request-Headers

I am trying to use an interceptor to add a custom header to every request in an AngularJS App using the following code:
angular.module('app').factory('httpRequestInterceptor', function () {
return {
request: function (config) {
config.headers['testheader'] = 'testheaderworks';
return config;
}
};
});
angular.module('app').config(function ($httpProvider) {
$httpProvider.interceptors.push('httpRequestInterceptor');
});
This code was copied from the answer to this question
Unfortunately, when I examine the resulting requests, I get the following:
Provisional headers are shown
Access-Control-Request-Headers:accept, testheader
Access-Control-Request-Method:GET
Origin:http://localhost:61577
Referer:http://localhost:61577/
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36
I confirmed this in both the network tab in Chrome and on the server side. Why is the custom header key 'testheader' added to Access-Control-Request-Headers rather than the general headers? What happened to the value? Is there another way to add custom headers to every AngularJS request that avoids this issue?
In case anyone reads this and is having the same issue:
The problem was that Angular was making a cross origin request, which the browser was preventing. In order to enable this request I had to enable the header on the server side. In our case (NodeJs) the code to do this was:
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Headers", testheader");
next();
});

Node.js Login to blog site and Create new post

I want to login to blogfa.com (a persian blog service) and create a new post by node.js
To do that i use request.js to post login site and go this url "/Desktop/Post.aspx?action=newpost" and post a new content
here is code i got so far :
var request = require('request');
var cheerio = require('cheerio');
var j = request.jar();
request = request.defaults({ jar : j }); //it will make the session default for every request
//...
var headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.89 Safari/537.36 OPR/28.0.1750.48',
'Content-Type': 'application/x-www-form-urlencoded'
};
request({
url:"http://blogfa.com/Desktop/login.aspx",
method:"POST",
form:{uid:"demoblog1",pwd:"test"},
headers: headers,
followRedirect:true
},
function(error,response,body){
console.log(body);
});
Problem i have its, i cant login in to the site .
i dont why not working ! i used jar for cookie , posted user and password , also set headers.
here is runnable code you can test :
http://code.runnable.com/Vc7EnmyVlgRa1Hx-/blog-login-for-node-js
Update
Request Cookies
.ASPXBLOG BC045A0CD184FEA10D91561EB67A302F1E036D88E50CE4264E4ABD003
__utma 36873331.1996897518.1435135939.1437159460.1439563539.7
__utmz 36873331.1437159460.6.6.utmcsr=chat.delgarm.com|utmccn=(referral)
pubset ar=1&z=12600&ds=0&cmt=0&cats=0&tag=0&nu=1&bt=dGVzdCB
ten 67145377
By default request does not follow redirects for non-GET requests, which is what is happening in this case. So set followAllRedirects: true in your request() options and it should work fine.

Categories

Resources