get auth portion of url with express.js - node.js

I'm building out an API using express.js
(its my first time doing this)
I want to authenticate requests by using the standard auth portion of the url. I want requests to come in as https:// {public-key}:{private-key}#host:port/path
I can't find the auth portion of the url anywhere. req.url is just /path
I found this How to get the full url in Express? which said to do the following:
req.protocol + "://" + req.get('host') + req.url
But that returns only https:// host:port/path
Any help would be great.
As a side note, if this isn't the standard way to authenticate APIs please let me know!

You can use express.basicAuth() middleware to get the username and password sent with the URL.
app.get('/',
express.basicAuth(function(username, password){
console.log(username);
console.log(password);
return (true);
}),
function(req,res){
...
});
Or like the conventional app.use fashion
app.use(express.basicAuth(function(user, pass){
return 'tj' == user & 'wahoo' == pass;
}));

Related

How can I get the current URL from app request in Node JS/ Express?

I don't know if it is possible but im trying to save the URL that came from app.use in a global variable and trying to access it in the next line. It turns that in the second line the variable is undefined.
Here is my code in my Node JS file:
app.use(function(req, res, next) {
global.CurrentURL = req.protocol + "://" + req.get('host') + req.originalUrl;
});
console.log(global.CurrentURL);
enter image description here
I need to save the current URL in the page so I can make validations with it. I think that the program doesn't go through that piece of code (app.use) is there any way I can force it to go through?

Google cloud functions replaces double slash in url

Im trying to deploy cors-anywhere on Google Cloud Functions. Im supposed to provide the url after gcp's link.
It looks like this :
https://us-central1-my-project.cloudfunctions.net/my-function/http://dummy.restapiexample.com/api/v1/employees
but it's transformed to :
https://us-central1-my-project.cloudfunctions.net/my-function/http:/dummy.restapiexample.com/api/v1/employees
All the double slashes after the host are transformed to simple ones.
I tried replacing req.url to transform http:/ to http:// but still wont work. Maybe this needs to be fixed in the webserver level.
Here's my function in GCP
var cors_proxy = require('cors-anywhere').createServer({
requireHeader: ['origin', 'x-requested-with'],
removeHeaders: [
'cookie',
'cookie2',
],
// See README.md for other options
});
exports.myFunction = (req, res) => {
req.url = req.url.replace('/my-function/', '/'); // Strip '/my-function' from the front of the URL, else the proxy won't work.
return cors_proxy.emit('request', req, res);
};
Anyone tried to deploy this in a serverless function?
You're using req.url which contains a normalized version of the request URL. You'll want to use req.originalUrl which, as the name suggests, retains the original requested URL. See Express docs for more info.

Any simple way to create link in ExpressJS?

Sometimes i need create a absolute link in a web site.
Like http://example.com/xxxx/xxxx?foo=bar not /xxxx/xxxx?foo=bar
Here has anyway to create a simple helper for express manually?
Just like:
app.locals.url = function ( pathTo, opts ) {
// Somethings here.
}
I think they may need SSL check, host and route check or somethings.
You can create the full URL :
var URL = req.protocol + '://' + req.get('host') + req.originalUrl;
Them You can redirect to this URL

Nodejs dynamic OG tags

Using Express. Here's the route. It basically just passes the url params into a template that renders the OG tags.
router.get('/share/:redirectURL/:title/:description/:img', function (req, res) {
var url = req.protocol + '://' + req.get('host') + req.originalUrl; // points to this endpoint
res.render('share', {
url: url,
title: decodeURIComponent(req.params.title),
img: decodeURIComponent(req.params.img),
description: decodeURIComponent(req.params.description),
redirectURL: decodeURIComponent(req.params.redirectURL)
});
});
module.exports = router;
And here's the share template that it renders to.
doctype html
html
head
meta(property="og:url", content="#{url}")
meta(property="og:image", content="#{img}")
meta(property="og:title", content="#{title}")
meta(property="og:description", content="#{description}")
meta(property="og:type", content="article")
body
script.
location.replace("#{redirectURL}");
...and it works! But it only works LOCALLY. As soon as I upload to the server, things go awry.
works: http://localhost/share/http%3A%2F%2Fgoogle.com/Hear%20some%20music./http%3A%2F%2F201.23.456.789%2F%2Fassets%2Fimgs%2Ffavicons%2Ficon1024.png
doesn't work: http://123.45.678.910/share/http%3A%2F%2Fgoogle.com/Hear%20some%20music./http%3A%2F%2F201.23.456.789%2F%2Fassets%2Fimgs%2Ffavicons%2Ficon1024.png
Something upstream is partially decoding the url BEFORE it gets to the Express router. The result is this confused, useless thing.
http://123.45.678.910/share/http:/google.com/Hear%20some%20music./http%3A%2F%2F201.23.456.789%2F%2Fassets%2Fimgs%2Ffavicons%2Ficon1024.png
Switched to query parameters and it works!

Node.js www - non www redirection

Is there a chance to somehow redirect www to non-www URLs in node.js? Since there is no htaccess in node web server I am curious how to do that.
Even though this question is nearly 3 years old, there are a few subtle issues with the previously posted answers (and their comments), as well as some good advice in the comments that didn't make it back into the answers themselves. Here's a few important things to note:
Don't hardcode the http:// or https:// in the redirect URI; this makes life suck when switching between dev and prod environments - use req.protocol instead.
Also note that in order to use req.protocol reliably behind a proxy performing SSL termination (such as Elastic Load Balancer), you need to make sure that the trust proxy setting is enabled. This will ensure that req.protocol returns the protocol that the browser sees, not the protocol that finally made it to your app server.
The accepted answer has a logic bug, as it matches on /^www/, but formats the redirect URI with /^www./. In practice that probably won't bite anyone, but it would result in infinite redirect loops for something like wwwgotcha.example.com.
Be sure to use req.headers.host instead of req.host, as the latter strips out the port number. So, if you were to handle a request for www.example.com:3000, you'd redirect the user to www.example.com, minus the correct port number.
As Dário pointed out, you'll typically want to use a 301 redirect when going from www to non-www (or vice versa) for SEO purposes.
The last issue is the most minor, but it's generally safer to use req.originalUrl when creating redirect URIs, just in case you happen to be running in a mounted "sub app".
All that being said, here's my recommended approach that takes the above into consideration:
function wwwRedirect(req, res, next) {
if (req.headers.host.slice(0, 4) === 'www.') {
var newHost = req.headers.host.slice(4);
return res.redirect(301, req.protocol + '://' + newHost + req.originalUrl);
}
next();
};
app.set('trust proxy', true);
app.use(wwwRedirect);
You're using express, right? If so you can make a route handler that all GET requests go through, checks if they're to a 'www' URL, and redirects to the appropriate non-www URL if appropriate.
app.get('/*', function(req, res, next) {
if (req.headers.host.match(/^www/) !== null ) {
res.redirect('http://' + req.headers.host.replace(/^www\./, '') + req.url);
} else {
next();
}
})
An updated version of jmar777's answer:
Using express
server.use((req, res, next) => {
if (req.headers.host.startsWith('www.')) {
const newHost = req.headers.host.slice(4)
return res.redirect(
301,
`${req.protocol}://${newHost}${req.originalUrl}`,
)
}
next()
})
This is a basic exemple of how you could mimic the behavior of the redirect directive of apache in nodejs.
The function redirect takes either a RegExp or a string.
var http, redirect;
http = require("http");
redirect = function(host, res, pattern, redirect){
if (host == pattern || (pattern instanceof RegExp && host.match(pattern))) {
console.log("Redirected " + host);
res.writeHead(302, {
'location': redirect
});
res.end();
}};
http.createServer(function(req, res){
redirect(req.headers.host, res, /^www/, 'http://plouf.url');
redirect(req.headers.host, res, 'www.plouf.url', 'http://plouf.url');
res.writeHead(200, {
'Content-Type': 'text/plain'
});
res.end('Hello World\n');
}).listen(8000, '127.0.0.1');
In the world of DevOps and the increasing adoption of hosted platforms, this type of thing should never be handled by code. You should handle the redirect using infrastructure instead. Putting this code into the application means that issues cannot be mitigated by the Operations team should something fail in the apex entry. In addition, while it is fancy and shiny and hip, using the apex as your site url limits the ability of Operations to redirect the site should something go wrong and causes issues when you want to do a blue/green, A/B testing or geo-redirection (in some cases). Your code and app should be url-agnostic.
I agree with Sebastian above with a minor tweak and if you are using Express. I would just make it a middleware it will be processed on all requests.
function removeWWW(req, res, next){
if (req.headers.host.match(/^www/) !== null ) {
res.redirect('http://' + req.headers.host.replace(/^www\./, '') + req.url);
} else {
next();
}
}
app.use(removeWWW);

Resources