Updates from September, 2014 Toggle Comment Threads | Keyboard Shortcuts

  • Richard 10:14 am on September 5, 2014 Permalink |  

    Redirecting to HTTPS in Node.js on Azure Websites 

    If you’ve got a node.js website running in Azure Websites, you get SSL by default, or if you bring your own domain name, you can easily set up SSL with your own certificate.

    The default behaviour is that the website serves both HTTP and HTTPS requests, but what if you want to switch users automatically over to HTTPS (i.e. disable HTTP).

    The normal approach when using express.js is to use some middleware which detects the protocol and redirects accordingly. Like this:

    // this doesn't work in Azure Websites
    function requireHTTPS(req, res, next) {
        if (!req.secure) {
            return res.redirect('https://' + req.get('host') + req.url);
        }
        next();
    }
    
    app.use(requireHTTPS);
    

    req.secure is just a shorthand for checking the protocol of the incoming request. However, in Azure websites your server is fronted by a web server running ARR, which does the SSL termination. This means the request you see will always be HTTP. The above code samples creates a redirect loop as the middleware continues to redirect to HTTPS, as it keeps seeing HTTP.

    Fortunately ARR adds some additional headers to the request. These are:

    cookie: ARRAffinity=71111a2979a8796b0cc6860d7f98cb7519aaea861cc96f15896edbb25a259064
    host: XYZ.azurewebsites.net
    max-forwards: 10
    x-liveupgrade: 1
    x-arr-log-id: 7cffa211-21f6-42c2-8b7d-e9eacac8adc8
    disguised-host: XYZ.azurewebsites.net
    x-site-deployment-id: XYZ
    x-original-url: /url
    x-forwarded-for: 212.69.41.154:4219
    x-arr-ssl: 2048|128|DC=com, DC=microsoft, DC=corp, DC=redmond, CN=MSIT Machine Auth CA 2|C=US, S=WA, L=Redmond, O=Microsoft, OU=OrganizationName, CN=*.azurewebsites.net 
    

    The x-arr-ssl header is only added for HTTPS requests, so we can use this header to determine whether it’s a HTTP or HTTPS request.

    function requireHTTPS(req, res, next) {
        if (!req.get('x-arr-ssl')) {
            return res.redirect('https://' + req.get('host') + req.url);
        }
        next();
    }
    
    app.use(requireHTTPS);
    

    You could go one better, and only do the upgrade if you’re running in Azure, which means you can run your site in plain HTTP in your local environment:

    function requireHTTPS(req, res, next) {
        if (req.get('x-site-deployment-id') && !req.get('x-arr-ssl')) {
            return res.redirect('https://' + req.get('host') + req.url);
        }
        next();
    }
    
    app.use(requireHTTPS);
    
     
    • stpdev 4:07 pm on September 23, 2015 Permalink | Log in to Reply

      Azure has it’s own method of handling HTTPS redirection. NodeJS apps in Azure are still manage through IIS runtimes.

      Their recommended approach is to add rewrite rules to the web.config.

      The web.config is only created after an initial deployment (easiest way to get it generated for all the node handling). You grab it via FTP credentials set up through the portal and simply add the rewrite rule to the existing rules in place.

      Once its there and you include it in the root dir of your deployed app, azure will use it.

  • Richard 1:39 pm on September 2, 2014 Permalink |  

    Using the Azure Search service from JavaScript 

    surface-your-data

    The new Azure Search service is a nice ‘search as a service’ offering from Microsoft. Just add your documents, and then run some queries. It’s exposed as a REST API which talks JSON :¬D

    It has a free tier, limited to 3 indexes and 10,000 documents, but you can of course start paying the money and index more stuff.

    I just wrote a JavaScript client (I couldn’t find a Microsoft one) to connect to the API, let’s explore how we can use it.

    Note this article assumes you are familiar with writing JavaScript for node.js and the browser.

    Creating the Search Service

    First, open up the new Azure Portal and go to NEW -> Search and enter some details in.

    You’ll need to switch to the free tier, otherwise you’ll start clocking up a bill.

    We’ll start off using Node.js, as only a few of the features (quite correctly) can be used from the browser.

    Once it’s created go to the properties and keys sections of the search service blade, and make a note of your url and an admin key.

    Installation

    First install the package:

    $ npm install azure-search
    

    Creating the Client

    Now let’s write write some JavaScript in node to create an index.

    var AzureSearch = require('azure-search');
    var client = AzureSearch({
        url: "https://MY_SEARCH_SERVICE_NAME.search.windows.net",
        key:"MY_SEARCH_SERVICE_KEY"
    });
    

    Creating the Index

    Now we have a client, we can create an index in the Search Service. To do this, we need to create a schema, which will tell the service what kind of data we want to store and search. There’s more information about how to create the schema in the Microsoft documentation, but for a simple example, I’ll have some text, and a key that I’ll use to refer to the text.

    var schema = { 
      name: 'myindex',
      fields:
       [ { name: 'id',
           type: 'Edm.String',
           searchable: false,
           filterable: true,
           retrievable: true,
           sortable: true,
           facetable: true,
           suggestions: false,
           key: true },
         { name: 'description',
           type: 'Edm.String',
           searchable: true,
           filterable: false,
           retrievable: true,
           sortable: false,
           facetable: false,
           suggestions: true,
           key: false } ],
      scoringProfiles: [],
      defaultScoringProfile: null,
      corsOptions:  { allowedOrigins: ["*"]} };
    
    client.createIndex(schema, function(err, schema){
      if (err) console.log(err);
      // schema created
    });
    

    Note that at the bottom of the file there’s a corsOptions setting which sets allowedOrigins to ["*"]. We’ll be using this later to access the index from the browser.

    Populating the Index

    Now we’re ready to start adding documents to the index. In the schema we specified id and description fields. So we just need to supply an object with these fields.

    var document = {
      id: "document1",
      description: "this is a document with a description"
    };
    client.addDocuments('myindex', [document], function(err, confirmation){
      if (err) console.log(err);
      // document added
    });
    

    In fact we can send through a batch of document through at once, by adding more items to the array.

    Querying the Index

    We can query the index from node, but the Search Service supports CORS, which allows us to query directly from the browser without having to stand up any of our own server-side infrastructure. This is where the CORS settings came in when we created the schema.

    One thing to be careful of; don’t put your Search Service admin key in a public web page. Instead, go back to the portal and use a query key (see the manage keys button when you’re looking at the keys).

    Untitled

    Now we can create a web page where we can call the index, and pass in some search queries. To do this we need to add a reference to azure-index.min.js (or use browserify, and just require ‘azure-index’).

    <html>
        <head>
            <script src="azure-search.min.js"></script>
        </head>
        <body>
            <script>
    
            var client = AzureSearch({
              url: "https://MY_SEARCH_SERVICE_NAME.search.windows.net",
              key:"MY_QUERY_KEY"
            });
    
            client.search('myindex', {search:'document'}, function(err, results){
              // results is an array of matching documents
            });
    
            </script>
        </body>
    </html>
    

    Note that from the browser, only search, suggest, lookup and count will work.

    For more information, please consult the Microsoft documentation and the documentation for the module.

    Conclusion

    The search service looks quite powerful. We’ve only scratched the surface of the options here. I’m keen to combine the search service with a trace listener, so you can index your application’s logging.

    It’s great to see Microsoft move away from the awkward API conventions used for the storage system, which included complicated header signing and XML. This JSON approach with a simple API key as a header is nice and simple.

    It’s also great to see CORS support our of the box, which makes it easy to consume this service directly from the browser.

    Personally I think API version number looks out of place on the URL, and would be better as a header, but maybe that’s just me.

    I also would prefer not to have to specify my schema. I’d like to just throw JSON objects at the service, and then be able to query on any of the fields, but I guess that’s DocumentDB!

     
c
Compose new post
j
Next post/Next comment
k
Previous post/Previous comment
r
Reply
e
Edit
o
Show/Hide comments
t
Go to top
l
Go to login
h
Show/Hide help
shift + esc
Cancel