How do you get RequireSSL in NodeJS on an Azure Website? - node.js

So a little background first: A NodeJS server running in an Azure Website will automatically have all HTTPS requests directed to the http endpoint. This allows the following code to work for both HTTP and HTTPS
var http = require('http');
var express = require('express');
var app = express();
// *snip*
http.createServer(app).listen(process.env.PORT);
// can go to http://*.azurewebsites.net or https://*.azurewebsites.net without issue
From here I decided to create a "RequireSSL" middleware
/* snip */
if (req.protocol === 'http') {
var origFullUrl: string = 'http://' + req.get('host') + req.originalUrl;
var u: url.Url = url.parse(origFullUrl, true);
u.host = null; // nead to clear so 'port' is used
u.protocol = 'https';
u.port = '443';
res.redirect(url.format(u));
}
/* snip */
Here's where the background comes into play. Because Azure redirects all HTTPS to the HTTP protocol the req.protocol always equals 'http' creating a redirect loop.
Anyone know of a way to get this to work in an Azure Website?

You can detect this using x-arr-ssl header.. Please go through this : https://coderead.wordpress.com/2014/09/05/redirecting-to-https-in-node-js-on-azure-websites/

Related

How to determine http vs https in nodejs / nextjs api handler

In order to properly build my urls in my xml sitemaps and rss feeds I want to determine if the webpage is currently served over http or https, so it also works locally in development.
export default function handler(req, res) {
const host = req.headers.host;
const proto = req.connection.encrypted ? "https" : "http";
//construct url for xml sitemaps
}
With above code however also on Vercel it still shows as being served over http. I would expect it to run as https. Is there a better way to figure out http vs https?
As Next.js api routes run behind a proxy which is offloading to http the protocol is http.
By changing the code to the following I was able to first check at what protocol the proxy runs.
const proto = req.headers["x-forwarded-proto"];
However this will break the thing in development where you are not running behind a proxy, or a different way of deploying the solution that might also not involve a proxy. To support both use cases I eventually ended up with the following code.
const proto =
req.headers["x-forwarded-proto"] || req.connection.encrypted
? "https"
: "http";
Whenever the x-forwarded-proto header is not present (undefined) we fall back to req.connection.encrypted to determine if we should serve on http vs https.
Now it works on localhost as well a Vercel deployment.
my solution:
export const getServerSideProps: GetServerSideProps = async (context: any) => {
// Fetch data from external API
const reqUrl = context.req.headers["referer"];
const url = new URL(reqUrl);
console.log('====================================');
console.log(url.protocol); // http
console.log('====================================');
// const res = await fetch(`${origin}/api/projets`)
// const data = await res.json()
// Pass data to the page via props
return { props: { data } }
}

Get my Action’s server URL in (JavaScript) fulfilment code

I am using actionssdk and I build my Action fulfilments using Javascript and node.js + Express.
I am looking for a way to get the url (protocol + host name + port) of the server where the fulfilment is hosted.
Is there a simple way to do this? E.g. in the MAIN intent? Is there some conv-property I can use? Can I get hold of a req-parameter in the MAIN-intent, from which I can deduct hostname etc?
const express = require('express');
const expressApp = express();
const { actionssdk, ... } = require('actions-on-google');
const app = actionssdk({
ordersv3: true,
clientId: ...
});
expressApp.post('/fulfilment', app);
app.intent('actions.intent.MAIN', (conv) => {
let myUrl: string = ... // ???????
...
});
(background: obviously I know myself to where I deployed my fulfilment code. But I have a reusable template for fulfilment code in which I want to refer to the host url, and I do not want to type that in manually each time I develop a new Action).
You can get access to the request object in a middleware via Framework Metadata which is by default of type BuiltinFrameworkMetadata which contains objects used by Express
For example, you can use it like this, which will be ran before each request:
app.middleware((conv, framework) => {
console.log(framework.express.request.headers.host)
})

HTTPS TLS Settings in Node

I was looking through my codebase today, the portion which sets up the server and found the following lines:
var https = require('https');
https.globalAgent.options.secureProtocol = 'TLSv1_2_method';
function createHttpsServer(app) {
var https = require('https');
var fs = require('fs');
const options = {
secureProtocol: 'TLSv1_2_method',
// ...
};
var server = https.createServer(options, app);
return server;
}
It looked like code duplication to me and I am not sure why these do different things (or do they?).
A colleague of mine told me that the top one is for controlling TLS in HTTPS requests made from NodeJS, which in turn, gives us access to the https.agent which is used for all things related to client HTTP requests.
This was also compared to the ServicePointManager in the .NET world.
So do these methods both do different things? At some point, our code does:
var server = protocol === 'https' ? createHttpsServer(app) : createHttpServer(app);
Wouldn't that be using the same server at the end of the day?
var server = protocol === 'https' ? createHttpsServer(app) : createHttpServer(app);
The above line creates the same server, the only difference is if the protocol is 'https' it will run on HTTPS server (this require SSL certificate) whereas if the protocol is http it will run on HTTP server.

Nodejs memory usage

I think I have a problem with memory usage. I have a node.js server :
var arcadeGames = require('./server/js/arcade');
var cardsGames = require('./server/js/cards');
requires modules that exports object required from .json data
var http = require('http');
var express = require('express');
var app = express();
var server = http.createServer(app);
//var io = require('socket.io').listen(server);
//var fs = require('fs');
app.get('/specificCategory/:id',function(req,res,next){
switch(req.params.id){
case "Cards":
console.log(cardsGames.titles);
break;
case "Action":
console.log(actionGames.titles);
break;
default:
console.log("undefined");
}
//var specificCaategory = require('./server/js/'+ req.params.id.toLowerCase());
//var categoryTitlesAndUrlThumbs = spe
//console.log(specificCaategory.titles);
})
(both way are working the same commented one or the one with switch)
the get function is called from browser by clicking the categories ex :Cards, Action and send the request through http, controller from angularjs. The problem is that when I console.loged out on server first click on each category works fine, but after that, the server takes a lot of time to console.log out the info.(what will happends in browser if this is so hard for server).
Have I done something to load the memory so much?
Add res.end(); after your switch case.

Use variable subdomains for routing with wildcard

I want to create an express application that uses dynamic/variable subdomains for routing. This is what I want to do:
http://<username>.mysite.dev should forward the requests to the users/index.js
In the users/index.js I will access the username via req.subdomain[0]. It would be nice if I could also run an regular expression check on <username>.
My first approach:
I am using the node package express-subdomain to route the requests:
/* import node packages */
var express = require('express'),
subdomain = require('express-subdomain');
/* application config */
var app = express(),
port = process.env.PORT || 3000;
/* import all apps */
var users = require('./users/index.js');
/* route requests by subdomain */
app.use(subdomain('*', users));
app.get('/', function(req,res) {
/* Never get here */
res.send('Homepage');
});
/* run app on given port */
app.listen(3000, function() {
console.log('Listening on port ' + port + ' ...');
});
The problem with this approach is that the * is not working properly. It forwards all requests to my users/index.js even when there is no subdomain (http://mysite.dev). One solution for this problem would be, if I change the routing like this:
app.use(subdomain('*.users', users));
So I can access the users/index.js through http://<user>.users.mysite.dev and I can also reach the normal site, when there is no subdomain. But this approach is not really what I want - the users subdomain is too much. In addition I can not use regex.
Now, I am searching for a better solution for this problem.

Resources