Simple Basic Authentication with Vanilla JavaScript (ES6)
app.use((req, res, next) => { // ----------------------------------------------------------------------- // authentication middleware const auth = {login: 'yourlogin', password: 'yourpassword'} // change this // parse login and password from headers const b64auth = (req.headers.authorization || '').split(' ')[1] || '' const [login, password] = new Buffer(b64auth, 'base64').toString().split(':') // Verify login and password are set and correct if (login && password && login === auth.login && password === auth.password) { // Access granted... return next() } // Access denied... res.set('WWW-Authenticate', 'Basic realm="401"') // change this res.status(401).send('Authentication required.') // custom message // ----------------------------------------------------------------------- })
Note: This "middleware" can be used in any handler. Just remove next() and change the logic. See Example 1 statement below or edit history for this answer.
What for?
req.headers.authorization contains the value " Basic <base64 string> ", but it can also be empty, and we do not want it to fail, so the strange combination || '' || '' || '' || ''- The node does not know
atob() and btoa() , therefore, Buffer
ES6 β ES5
const just var .. view
(x, y) => {...} it's just function(x, y) {...}
const [login, password] =...split() are just two var assignments in one
source of inspiration (uses packages)
The above is a
very simple example, which was supposed to be
very short and quickly deployable on a playground server. But, as noted in the comments, passwords can also contain colon characters
: To correctly extract it from b64auth, you can use this.
// parse login and password from headers const b64auth = (req.headers.authorization || '').split(' ')[1] || '' const strauth = new Buffer(b64auth, 'base64').toString() const splitIndex = strauth.indexOf(':') const login = strauth.substring(0, splitIndex) const password = strauth.substring(splitIndex + 1) // using shorter regex by @adabru // const [_, login, password] = strauth.match(/(.*?):(.*)/) || []
Basic authentication in one statement
... on the other hand, if you use only one or very few login names, this is a necessary minimum: (you donβt even need to analyze the credentials at all)
function (req, res) { //btoa('yourlogin:yourpassword') -> "eW91cmxvZ2luOnlvdXJwYXNzd29yZA==" //btoa('otherlogin:otherpassword') -> "b3RoZXJsb2dpbjpvdGhlcnBhc3N3b3Jk" // Verify credentials if ( req.headers.authorization !== 'Basic eW91cmxvZ2luOnlvdXJwYXNzd29yZA==' && req.headers.authorization !== 'Basic b3RoZXJsb2dpbjpvdGhlcnBhc3N3b3Jk') return res.status(401).send('Authentication required.') // Access denied. // Access granted... res.send('hello world') // or call next() if you use it as middleware (as snippet
PS: do you need to have both a "safe" and a "public" path? Try using express.router .
var securedRoutes = require('express').Router() securedRoutes.use() securedRoutes.get('path1', ) app.use('/secure', securedRoutes) app.get('public', )