Enabling CORS in Nancy

⚠️
This article is out of date.
Nancy is no longer maintained. Since then, ASP.NET Core has implemented many of the features Nancy offered. Rather use that for all future development.

We use Nancy for a product that we have developed in-house. One of the features that we have implemented in the product is a REST Api so that we can integrate the product into other applications. Nancy does a great job at this as it allows us to easily separate the REST Api into NancyModules which are then detected at runtime when the product is started. This lets us add REST Api modules without having to touch or rebuild other REST Api modules since we just create a new package for it and place it in the executing directory of the Nancy product and it picks it up automagically.

This works well, however, one issue that I run into frequently when creating new REST Api modules is remembering to enable CORS (Cross-Origin Resource Sharing) otherwise it isn't possible to call the REST Api from Javascript on another domain. This happens so often and I find myself forgetting how to do it every time, I decided to write a post so I don't forget (and to help you solve the same issue).

Solution

The solution I found on StackOverflow is quite simple to implement. It is done on a NancyModule-level which means you have the choice of exposing certain modules to certain domains. Say a certain client needs a particular REST Api, you can implement the Api and only give their domains permission to use it. This is great when offering integration solutions tailored for an application.

To enable CORS, simply insert the following line of code in the constructor of your NancyModule (I usually put it at the very top) as follows:

using Nancy;

namespace SampleNamespace
{
    public class SampleModule : NancyModule
    {
        public SampleModule()
        {
            // Enable cors
            After.AddItemToEndOfPipeline((ctx) =>
            {
                ctx.Response.WithHeader("Access-Control-Allow-Origin", "*")
                    .WithHeader("Access-Control-Allow-Methods", "POST,GET")
                    .WithHeader("Access-Control-Allow-Headers", "Accept, Origin, Content-type");
            });

            // Other stuff that happens...
        }
    }
}

This code will add the necessary headers to the response to enable CORS, but what does each header mean?

Access-Control-Allow-Origin

This header specifies what domains are allowed to access the NancyModule. This can either be set to a * to allow all domains access to the module, or a list of domains separated by a comma (e.g. https://www.ivankahl.com, https://www.google.com) so that only those specified domains can access the module.

NOTE: It is a very good idea to specify the exact domains that can access the REST Api rather than leaving it available to all domains (i.e. *)

You can read more about this here.

Access-Control-Allow-Methods

This specifies what methods are permitted when accessing the NancyModule. This is usually the GET and POST methods although you can specify more. Multiple methods are also separated by a comma (e.g. GET,POST).

You can read more about this header here.

Access-Control-Allow-Headers

This specifies what headers can be used by the client to make the actual request. I have included the headers that work for me in the code snippet above. You can add or remove whatever headers you need to allow.

There is also more information on this header here.

Conclusion

I hope this solution helps you. I think it is a simple fix to a problem that can become very frustrating very quickly. If you know of any other ways to enable CORS in Nancy, please leave them below.