Dojo rpc.JsonService - set custom header - javascript

Dojo v1.6.0.
Is there any way to set custom header (spring csrf protection in my case) to every call for all instances of dojo.rpc.JsonService()?
Or at least to every call for specific instances of dojo.rpc.JsonService()?
Problem is in back-end Spring 4 csrf protection which filters everything without specific header in request and returns HTTP 403 Forbidden status.
For now my code looks like:
...
dojo.require("dojo.rpc.RpcService");
dojo.require("dojo.rpc.JsonService");
var myService = new dojo.rpc.JsonService("someMyService");
var result = myService.myRemoteMethod(param1, param2, ... );
...
For example for jQuery code which handles every ajax request and set header to it looks like:
var token = $("meta[name='_csrf']").attr("content");
var header = $("meta[name='_csrf_header']").attr("content");
$(document).ajaxSend(function (e, xhr, options) {
xhr.setRequestHeader(header, token);
});
It would be perfect to make something like that for dojo.

I haven't found any solution for dojo 1.6, but found that I can fix this problem with handling every ajax request with pure javascript as explained here
So my final solution is:
(function(send) {
var token = $("meta[name='_csrf']").attr("content");
var header = $("meta[name='_csrf_header']").attr("content");
XMLHttpRequest.prototype.send = function(data) {
if (isNotBlank(token) && isNotBlank(header)) {
this.setRequestHeader(header, token);
}
send.call(this, data);
};
})(XMLHttpRequest.prototype.send);

Related

CORS with Akka-Http and Spray

I'm trying to send http requests from a local file (client) to my backend server.
After reading countless articles on how to enable CROS (cross-origin-resource-sharing), I'm still getting the error: "Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. The response had HTTP status code 405."
For my backend server, I use Akka-Http and Spray-Json. As a result, I decided to use akka-http-cors (https://github.com/lomigmegard/akka-http-cors), but that didn't seem to solve the problem either. I understand that I should be using the options directive and 'Access-Control-Allow-Origin'(fileName), but I can't seem to figure out how to use them correctly.
I've attached snippets of my backend and javascript code. If anyone knows how to properly enable CROS between my client and server that would be amazing.
Backend scala-akka-spray code
var signInUrl = 'http://0.0.0.0:8080/user/sign-in';
function sendEntry(form, signType) {
var jsonString = serializeEntry(form);
var httpRequest = new XMLHttpRequest();
httpRequest.open('POST', signInUrl, true); // true meanining asynchronous
httpRequest.setRequestHeader('Content-type', 'application/json');
httpRequest.send(jsonString);
}
I was able to get this working through the code listed at https://dzone.com/articles/handling-cors-in-akka-http
Copied here for completion:
import akka.http.scaladsl.model.HttpMethods._
import akka.http.scaladsl.model.headers._
import akka.http.scaladsl.model.{HttpResponse, StatusCodes}
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.directives.RouteDirectives.complete
import akka.http.scaladsl.server.{Directive0, Route}
import scala.concurrent.duration._
/**
* From https://dzone.com/articles/handling-cors-in-akka-http
*
*
*/
trait CORSHandler {
private val corsResponseHeaders = List(
`Access-Control-Allow-Origin`.*,
`Access-Control-Allow-Credentials`(true),
`Access-Control-Allow-Headers`("Authorization",
"Content-Type", "X-Requested-With"),
`Access-Control-Max-Age`(1.day.toMillis)//Tell browser to cache OPTIONS requests
)
//this directive adds access control headers to normal responses
private def addAccessControlHeaders: Directive0 = {
respondWithHeaders(corsResponseHeaders)
}
//this handles preflight OPTIONS requests.
private def preflightRequestHandler: Route = options {
complete(HttpResponse(StatusCodes.OK).
withHeaders(`Access-Control-Allow-Methods`(OPTIONS, POST, PUT, GET, DELETE)))
}
// Wrap the Route with this method to enable adding of CORS headers
def corsHandler(r: Route): Route = addAccessControlHeaders {
preflightRequestHandler ~ r
}
// Helper method to add CORS headers to HttpResponse
// preventing duplication of CORS headers across code
def addCORSHeaders(response: HttpResponse):HttpResponse =
response.withHeaders(corsResponseHeaders)
}
Using it as:
private val cors = new CORSHandler {}
val foo: Route = path("foo") {
//Necessary to let the browser make OPTIONS requests as it likes to do
options {
cors.corsHandler(complete(StatusCodes.OK))
} ~ post( cors.corsHandler(complete("in foo request")) )
}
More details: https://ali.actor/enabling-cors-in-akka-http/
May be useful for someone: I just added a cors() directive and it did the trick for me:
import ch.megard.akka.http.cors.scaladsl.CorsDirectives.cors
val route: Route = cors() { // cors() may take optional CorsSettings object
get {...}
}

How to pass cookie as header in angularjs to a remote application that uses drupal [403 Forbidden]

Good day, I am trying to make a $http get request to a remote application that uses drupal in agular.js. Everytime I make a get request i get a 403 response saying [annonymus user]. I am able to make a put request and get a response with a token, session_name, and session_id. My problem is I am not sure how to pass the cookie as part of the request headers. ** **I tried passing cookies as the headers and I still get a 403 response. Any advice will help. I even tried to use $cookie.put('KEY,cookie) to save the cookie but still I get the same response.
var headers = {'Content-Type':'application/json','Cookie':xxxxxx=tokexxxx};
$http.get(url,headers).success(function(data){
// response of the results
console.log('this is the repsonse that come from the get request', response);
}).error(function(err){// 403 error});
My LogIn service looks like this
angular.module('app.services', []).service('LoginService', function($rootScope,$q,$http,$cookies) {
// this is the function that is called when ther user logins
var service = {};
// get cridentials of the user
service.LogIn = function(username,password,callback){
var loginStatus = [];
var BASEURL= http://xxxxxx.com';
var parameters ={username: username,password: password};
var headers = {'Content-Type':'application/json'}
$http.post(BASEURL,parameters,headers).success(function (response) {
// cookie.put
// console.log('response::', {sessionid,token,session,user_data}
$cookies.put(response.session_name,response.token); //
console.log(response.session_name,response.token);
localStorage.setItem('sessid',response.sessid); // locastorage
localStorage.setItem('token',response.token);
console.log(response);
return callback(response); //call this on the controller
});
}
maybe try instead of "cookie:" put "xsrfCookieName" and provide the cookie name.
it should use the token it has in it.
var headers = {'Content-Type':'application/json','xsrfCookieName':'cookieName'};
hope it helps

Node.js can't request a squarespace site?

I'm trying to request this website but I keep getting a 400 Bad Request error. This code works for just about any other site I've tried that isn't built with squarespace so I'm guessing that's where the problem is.
var request = require('request');
var cheerio = require('cheerio');
var url = 'http://www.pond-mag.com/';
request(url, function(error, resp, body){
if(!error){
var $ = cheerio.load(body);
console.log(body);
}
});
Figured it out just had to manually set the headers object.
Heres the code that fixed it in case anyone else has the problem:
var options = {
url : 'http://www.pond-mag.com/',
headers: {
'User-Agent': 'request'
}
};
Then, just pass the options var to the request instead of the url.
I use Squarespace for a lot of different apps and thought it was worth mentioning that Squarespace has native support for getting the JSON of any Squarespace page. If you append ?format=json to the URL you can pull make the request and get JSON back.

How to access request body in "onResourceRequested" callback in PhantomJS?

I would like to access the request body of HTTP POST requests in the callback registered with onResourceRequested (I didn't find it in the documentation).
I would like to do something like this:
page.onResourceRequested = function(requestData, networkRequest) {
var body = networkRequest.body // how to do that ?
console.log(body)
}
How can I access the body of the request in the onResourceRequested callback ?
The request body of POST requests are stored in the postData attribute of requestData object. You can retrieve it like so:
page.onResourceRequested = function(requestData, networkRequest) {
var body = networkRequest.postData
console.log(body)
}
To note, there doesn't seem to currently be a way to retrieve the request body for any other request methods such as PUT or PATCH.

JS/jQuery get HTTPRequest request headers?

Using getAllResponseHeaders in the xhr object, is possible to get all the response headers after an ajax call.
But I can't found a way to get the Request headers string, is that possible ?
If this is for debugging purposes then you can just use Firebug or Chrome Developer Tools (and whatever the feature is called in IE) to examine the network traffic from your browser to the server.
An alternative would be to use something like this script:
$.ajax({
url: 'someurl',
headers:{'foo':'bar'},
complete: function() {
alert(this.headers.foo);
}
});
However I think only the headers already defined in headers is available (not sure what happens if the headers are altered (for instance in beforeSend).
You could read a bit more about jQuery ajax at: http://api.jquery.com/jQuery.ajax/
EDIT: If you want to just catch the headers on all calls to setRequestHeader on the XMLHttpRequest then you can just wrapp that method. It's a bit of a hack and of course you would need to ensure that the functions wrapping code below is run before any of the requests take place.
// Reasign the existing setRequestHeader function to
// something else on the XMLHtttpRequest class
XMLHttpRequest.prototype.wrappedSetRequestHeader =
XMLHttpRequest.prototype.setRequestHeader;
// Override the existing setRequestHeader function so that it stores the headers
XMLHttpRequest.prototype.setRequestHeader = function(header, value) {
// Call the wrappedSetRequestHeader function first
// so we get exceptions if we are in an erronous state etc.
this.wrappedSetRequestHeader(header, value);
// Create a headers map if it does not exist
if(!this.headers) {
this.headers = {};
}
// Create a list for the header that if it does not exist
if(!this.headers[header]) {
this.headers[header] = [];
}
// Add the value to the header
this.headers[header].push(value);
}
Now, once the headers have been set on an XMLHttpRequest instance we can get them out by examining xhr.headers e.g.
var xhr = new XMLHttpRequest();
xhr.open('get', 'demo.cgi');
xhr.setRequestHeader('foo','bar');
alert(xhr.headers['foo'][0]); // gives an alert with 'bar'
Something you could to is use Sinon's FakeXMLHttpRequest to replace your browser's XHR. It's described in this document on how to use it for testing but I'm pretty sure you can use the module for your debugging purposes.
What you need to do is:
var requests;
this.xhr = sinon.useFakeXMLHttpRequest();
this.xhr.onCreate = function(xhr) {
requests.push(xhr);
}
And then later on, you can check your requests array for headers by:
console.log(requests[0].requestHeaders);
To access your request headers.

Categories