I am working on express js and in the incoming POST request, the username and password are present in the body of the request, I want to implement routing such that an authorisation header can be added to the incoming req object
My routing is as follows :
router.route('/token')
.post(function(req,res,next){
if(req.body.client_id){
//set headers for authentication, e.g "Authorization":"Basic dskvnksnsnjsnvsnlvnsd"
next();
}
},authController.isClientAuthenticated,oauth2Controller.token);
You can add headers by using the req.headers property:
req.headers.authorization = 'Basic ...'
Note that there is a res.headersSent property, which can be used to determine if headers have already been sent to the client, otherwise you will encounter an error.
Related
I'm trying to understand how authorization works after headers with data were set. I'm using passport and jwt to auth user and setting authorization headers after succeed login attempt.
res.setHeader('authorization', 'JWT ' + token);
console.log(res.getHeader('authorization'));
// prints JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwidXNlcl9wYXNzd29yZCI6IiQyeSQxMiR1VUh3czBoeXVYSFhjWTFXWFd2L21ldlNZUFBZcm4xLjdmdEwxb1RSN29mQmxDMEpERE5uLiIsInVzZXJfyMDc1NzM1LCJleHAiOjE1MzQ2Njc3MzV9.F4j6eXpbhPLsLOAixwyNT6PLOUhna1C6CA4iIVbidXsbmFtZSI6ImFkbWluIiwiaWF0IjoxNTM
and for example on my main router where only logged in users should be allowed to enter I can't catch this header? It seems like after setting this header its only working until the page is being reloaded. I made previous question about it but it wasn't specific enough.
I'm starting to think how authorization works and how to set headers or cookies or something after succeed passport authentication?
What you need is an interceptor to be created for your http requests where you'll inject the rules for setting headers with each response
var http = require('http');
http.Interceptor.register({
test: {
uri: '/me/friends',
host: 'graph.facebook.com'
},
rule: {
response: {
headers: {
'Set-Cookie': 'AuthSessId=41D3D0110BA61CB171B345F147C089BD; path=/',
'Content-Type': 'application/json'
}
uri: /^\/dialog\/oauth/,
host: 'www.facebook.com'
});
You can use this npm package for the same and ollow the documentation
Please visit https://www.npmjs.com/package/node-interceptor
In one of my projects I use the JxBrowser in a Netbeans application where my ReactApp is running.
I want to send a post request from the ReactApp and intercept it in my custom Protocol Handler in the JxBrowser.
The request is done via 'superagent':
request
.post('http://my-url')
.send({test: 'it'})
.set('Accept', 'application/json')
.set('Content-Type', 'application/json')
.end(callback)
I receive the request in my ProtocolHandler but I do not know how to get the post body out of the request.
urlRequest.getUploadData() //<-- returns null
What is the correct way to get the posts body here?
You're making a cross-origin request. A preflight "OPTIONS" request is sent in this case and you need to handle it properly in your ProtocolHandler. In this particular case you should set the certain headers telling the browser that the requested features are allowed:
if (request.getMethod().equals("OPTIONS")) {
URLResponse urlResponse = new URLResponse();
String origin = request.getRequestHeaders().getHeader("Origin");
HttpHeadersEx headers = urlResponse.getHeaders();
headers.setHeader("Access-Control-Allow-Methods", "POST");
headers.setHeader("Access-Control-Allow-Headers", "Content-Type");
headers.setHeader("Access-Control-Allow-Origin", origin);
urlResponse.setStatus(HttpStatus.OK);
return urlResponse;
}
Also, in order to allow JxBrowser to detect the POST data type properly, you should set the "Content-Type" request header with the corresponding value. In this case it should be the "application/x-www-form-urlencoded".
request
.post('http://my-url')
.send({test: 'it'})
.set('Accept', 'application/json')
.set('Content-Type', 'application/x-www-form-urlencoded')
.end(callback)
Then you'll receive a POST request with your data. I recommend that you take a look at the following article that contains the details related to CORS: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
If you're making a request to the same origin, you can avoid handling cross-origin requests just by setting the proper "Content-Type" header.
I am running my node/express js application on localhost. I am making a 'GET' request to Instagram's api and keep getting this error:
XMLHttpRequest cannot load https://api.instagram.com/oauth/authorize/?client_id=******&redirect_uri=http://localhost:4000/feed&response_type=code.
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://localhost:4000' is therefore not allowed access.
I make the request in my server like this:
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Headers: x-requested-with");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
app.get('/',function(req,res){
res.redirect(redirected to feed route);
})
app.get('/feed',function(req,response) {
var code = req.query.code;
var url = "https://api.instagram.com/oauth/access_token";
var options = {
url: url,
method: "POST",
form: {
client_id : clientId,
client_secret : client_secret,
grant_type: 'authorization_code',
redirect_uri: redirect_uri,
code: code
},
json: true
}
request(options, function(err,res,body){
var instagram_response = body;
response.json({access_info:instagram_response});
})
})
Getting data from visiting '/' in my server route works fine. When I call the server '/' route in the client side (when Gallery.html loads) using jQuery like below it gives me the error. Below is the function that runs when gallery.html is loaded in the client side.
$(function(){
$.get("/", function( instagram_reponse, access_token) {
access_token = instagram_reponse.access_token;
})
})
Am I getting this error because my node server is running on localhost? What am I doing wrong?
You need CORS package to be installed on node..
$ npm install cors
var express = require('express')
, cors = require('cors')
, app = express();
app.use(cors());
app.get('/products/:id', function(req, res, next){
res.json({msg: 'This is CORS-enabled for all origins!'});
});
app.listen(80, function(){
console.log('CORS-enabled web server listening on port 80');
});
Configuration Options
origin: Configures the Access-Control-Allow-Origin CORS header. Expects a string (ex: "http://example.com"). Set to true to reflect the request origin, as defined by req.header('Origin'). Set to false to disable CORS. Can also be set to a function, which takes the request origin as the first parameter and a callback (which expects the signature err [object], allow [bool]) as the second. Finally, it can also be a regular expression (/example.com$/) or an array of regular expressions and/or strings to match against.
methods: Configures the Access-Control-Allow-Methods CORS header. Expects a comma-delimited string (ex: 'GET,PUT,POST') or an array (ex: ['GET', 'PUT', 'POST']).
allowedHeaders: Configures the Access-Control-Allow-Headers CORS header. Expects a comma-delimited string (ex: 'Content-Type,Authorization') or an array (ex: ['Content-Type', 'Authorization']). If not specified, defaults to reflecting the headers specified in the request's Access-Control-Request-Headers header.
exposedHeaders: Configures the Access-Control-Expose-Headers CORS header. Expects a comma-delimited string (ex: 'Content-Range,X-Content-Range') or an array (ex: ['Content-Range', 'X-Content-Range']). If not specified, no custom headers are exposed.
credentials: Configures the Access-Control-Allow-Credentials CORS header. Set to true to pass the header, otherwise it is omitted.
maxAge: Configures the Access-Control-Allow-Max-Age CORS header. Set to an integer to pass the header, otherwise it is omitted.
preflightContinue: Pass the CORS preflight response to the next handler.
Refer this for more details https://www.npmjs.com/package/cors
I have a ExternalServe (running on Localhost)
When I using Browser to request:
localhost:2013/ExternalServer/getfilebyname?filename=getStatus.json
Then browser downloaded getStatus.json to Download Folder.
In my NodeJS project, I want to download getStatus.json file and I made:
download.js
var http = require('http');
var fs = require('fs');
function getFile (){
var file = fs.createWriteStream("./../lib/user.json");
var req = http.get("http://localhost:2013/ExternalServer/getfilebyname?filename=getStatus.json", function(res) {
res.pipe(file);
});
}
getFile();
but when i run: node download.js the system return
<html><head><title>Apache Tomcat/8.0.0-RC1 - Error report</title><style><!--H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #525D76;}--></style> </head><body><h1>HTTP Status 401 - </h1><HR size="1" noshade="noshade"><p><b>type</b> Status report</p><p><b>message</b> <u></u></p><p><b>description</b> <u>This request requires HTTP authentication.</u></p><HR size="1" noshade="noshade"><h3>Apache Tomcat/8.0.0-RC1</h3></body></html>
How to fix it?
Best regard
You are getting the following error response:
This request requires HTTP authentication
Suggesting to add the Authorization information in header. Like:
var options = {
host: 'localhost',
port: 2013,
path: '/ExternalServer/getfilebyname?filename=getStatus.json',
headers: {
'Authorization': 'Basic ' + new Buffer(uname + ':' + pword).toString('base64')
}
};
request = http.get(options, function(res) {
res.pipe(file);
});
in case of proxy, you can use the following header instead:
Proxy-Authorization
The server wants a username and password, or requires another authorization mechanism, before it will let you access the file this way.
To see how to supply a user and password when making the request in node.js, look at How to use http.client in Node.js if there is basic authorization
How do we know this could be the problem?
Two interesting strings in the system return:
HTTP Status 401
and
This request requires HTTP authentication
From Wikipedia: List of HTTP Status Codes
401 Unauthorized Similar to 403 Forbidden, but specifically for use
when authentication is required and has failed or has not yet been
provided.[2] The response must include a WWW-Authenticate header field
containing a challenge applicable to the requested resource. See Basic
access authentication and Digest access authentication.
Another possibility is that a server could be set up to emit 401 instead of 403, but doesn't really accept any usernames or passwords.
I need to set my custom http 'User-Agent header when I'm rendering my index.html page in Express.js app.
This doesn't help:
req.headers['user-agent'] = 'myHeader';
Is this possible?
The User-Agent header is sent by an HTTP client(browser) and is meant to be read by a server, for e.g., for Content Negotiation.
You cannot set a request header in a response, it can only be read. Moreover, the req object(IncomingMessage) passed to createServer() callback is a Readable stream.
However, a request can be initiated with a customer header using:
var headers = {'User-Agent': 'Ryan Dahl'};
http.request({hostname: 'nodejs.org', headers: headers}, function(res) {
});