Showing posts with label secure. Show all posts
Showing posts with label secure. Show all posts

Sunday, 23 July 2023

Secure (HTTPS) Your Non-Prod Next.JS Headless Sites

Preface: this isn't something you'll want to want to use in production, but great for non-prod or local environments!

If you're running Sitecore on Windows servers (not Azure PaaS where you can simply get a free managed certificate), and want to re-use your infrastructure (eg. in a non-prod environment or for testing purposes) you may choose to use that same Windows machine to run your headless app. This can save on costs, energy that can be spent on development (or setting up production), and help just to keep things simple.
Obviously there are heaps of hosting providers such as Vercel where you could run it, and if that's an option that works for you I would certainly recommend it. If not, read on...

The simplest way would be to copy your code to the same server - in a new folder beside your Sitecore installation - install Node and run: npm start:production. This will start your app on port 3000 (or whatever port you have configured).

This is fine if you just want to preview your app, but if you want it to work inside of Experience Editor, and your CM instance is using https, you'll need your app to also be served securely (or else you'll see a very broken site!).

Obtaining a Domain Name

I'm not going to tell you how to go about getting a domain name. Presumably if you've got Sitecore up and running somewhere you know how to go about getting a domain name, or already have one (and/or can use a sub-domain). I'm a fan of Namecheap, but whatever is cheapest/easiest!

Obtaining a Free Certificate

Easiest way to get a free certificate (on pretty much any system) these days? LetsEncrypt!

  1. Download CertBot from the letsencrypt site
  2. Install it
  3. Temporarily stop your IIS server (if it's running) so that Certbot can use its own server
  4. Request a certificate by running:
    certbot certonly --standalone -d "*.your.domain.com"
    (or any of the other methods such as DNS validation)
  5. Start your IIS (if you stopped it in #3 above)

HTTPS Using the Certificate

Since we're using Node anyway to run the headless app, we can make use of the local-ssl-proxy package to proxy your app through HTTPS with a single line!.

  1. Open a command prompt and run:
    npx local-ssl-proxy --key C:\Certbot\archive\your.domain.com\privkey1.pem --cert C:\Certbot\archive\your.domain.com\cert1.pem --source 443 --target 3000
    (obviously substitute your port 443 for anything else if it's occupied!)

Simple as that! It's so easy there's no excuse not to be using HTTPS for non-prods (or even local!) :)

Wednesday, 10 May 2023

Locking down requests from Sitecore to Head

For those coming from on-prem or PaaS the leap to the exciting new world of Sitecore SaaS can be quite daunting, with many new factors and considerations - not the least of which is security (which should always be front-of-mind).  Your dev teams may be busy brushing up on containers and headless, but infra teams will be more concerned with integrating with XM Cloud, most notably with the Head.

Most of you will (hopefully) already be familiar with a couple of the ways that communication between the Head and Sitecore can be secured:

  1. A Sitecore API key - allows you to lock down your API calls to the Layout Service and GraphQL endpoints, as well as impersonate users.
  2. The JSS Editing Secret - used as a shared key to ensure the app and Sitecore Editor are the only parties authorized to talk to one another while in Experience Editor mode.

But what if you want a bit of extra security? Say you have a WAF (something to that effect) which only allows certain headers? As always, Sitecore is nice and extensible:

The class making the HTTP call to your Head app is Sitecore.JavaScriptServices.ViewEngine.Http.RenderEngine and it creates a HttpClient to make the requests using Sitecore.JavaScriptServices.ViewEngine.Http.HttpClientFactory which has the following method:

public IHttpClient Create(HttpRenderEngineOptions options)
{
	Assert.IsNotNull(options, "options");
	return new TimeoutCapableWebClient(options.RequestTimeoutMs)
	{
		Encoding = Encoding.UTF8,
		Headers = { [HttpRequestHeader.ContentType] = "application/json" }
	};
}

This HttpClientFactory is created through DI, so you can just inject your own and add your own headers! Too easy!