0

I have a backbone application running on an Express server in Node.js.

I built my application using http and now I want to switch to https.

Since it is a single page application that resides mainly on the client, it is not enough to create two servers to listen to http and https and then redirect all http calls to https:

var express = require('express'),
    http = require('http'),
    https = require('https');

var app = express();

// keys for https server
var hskey = fs.readFileSync('./keys/my-key.pem');
var hscert = fs.readFileSync('./keys/my-cert.pem')

var options = {
    key: hskey,
    cert: hscert
};

// Middleware to redirect http calls to https
app.use(function(req, res, next) {

  if(!req.secure) {
    return res.redirect(['https://', req.get('Host'), req.url].join(''));
  } 
  next();

});

// http server listening on port 80
http.createServer(app).listen(80);

// https server listening on port 443
httpscreateServer(options, app).listen(443);

With backbone, calls to the server are done via AJAX, quoting backbonejs.org:

"Backbone.sync is the function that Backbone calls every time it attempts to read or save a model to the server. By default, it uses jQuery.ajax to make a RESTful JSON request and returns a jqXHR."

And you can't make a redirection after an AJAX. You need to do it yourself in Javascript. (res.redirect from POST).

So the middleare redirection in the server that I wrote above is not useful for this case.

Then, I thought I could change the url in the AJAX calls to "https://" instead of using a relative url:

$.ajax ({
      url:'https://www.mydomain.com/api/getMyBooks',
      type:'GET',
      dataType:"jsonp"
});

I had to change the dataType to jsonp in order to avoid cross-domain errors.

Ok, this seems to work, but how do I get to change the url in the browser to show a secure connection (https)?

I also changed the url defined in the Backbone models:

Entities.BookCollection = Backbone.Collection.extend({
    url: "https://localhost:4567/books",
    model: Entities.Book
});

But changing the url in Backbone models and collections here is what I got:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://www.mydomain.com/api/getMyBooks. This can be fixed by moving the resource to the same domain or enabling CORS.

But I'm in the same domain, since I'm working on localhost.

I don't find a good solution to switch from http to https. I'm stuck, any help would be appreciated.

Community
  • 1
  • 1
Yaiza
  • 11
  • 3

1 Answers1

0

Finally, I think I found the solution. You don't have to change the AJAX calls or the url in models and collections.

You need to do the redirection when you start your Backbone application:

BookManager.on("initialize:after", function(){

  if(Backbone.history){

    require(["apps/book/book_app"], function () {

      Backbone.history.start();

        if (window.location.protocol === 'http:') {
          window.location = "https://localhost:4567/#"+ BookManager.getCurrentRoute();
        }

    });
  }
});

I check if the url entered is http or https and if it is https then do the redirection using window.location.

You still need to create two servers to listen to http and https connections.

This works for me. Not sure if there is a better approach.

Yaiza
  • 11
  • 3