world nodejs node hello guide example node.js http express http-authentication

node.js - nodejs - Autenticación HTTP básica con Node y Express 4



nodejs server example (8)

Parece que implementar la autenticación HTTP básica con Express v3 era trivial:

app.use(express.basicAuth(''username'', ''password''));

La versión 4 (estoy usando 4.2) eliminó el middleware basicAuth , así que estoy un poco atascado. Tengo el siguiente código, pero no hace que el navegador solicite credenciales al usuario, que es lo que me gustaría (y lo que imagino que hizo el método anterior):

app.use(function(req, res, next) { var user = auth(req); if (user === undefined || user[''name''] !== ''username'' || user[''pass''] !== ''password'') { res.writeHead(401, ''Access invalid for user'', {''Content-Type'' : ''text/plain''}); res.end(''Invalid credentials''); } else { next(); } });


Autenticación básica simple con JavaScript vanilla (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) { res.set(''WWW-Authenticate'', ''Basic realm="401"'') // change this res.status(401).send(''Authentication required.'') // custom message return } // ----------------------------------------------------------------------- // Access granted... next() })

¿Por qué?

  • req.headers.authorization contiene el valor " Basic <base64 string> ", pero también puede estar vacío y no queremos que falle, de ahí el extraño combo de || '''' || ''''
  • El nodo no conoce atob() y btoa() , de ahí el Buffer

ES6 -> ES5

const es solo var .. tipo de
(x, y) => {...} es solo function(x, y) {...}
const [login, password] = ...split() es solo dos asignaciones var en una

fuente de inspiración (usa paquetes)

Lo anterior es un ejemplo súper simple que fue diseñado para ser súper corto y rápidamente desplegable en el servidor de tu patio de recreo. Pero como se señaló en los comentarios, las contraseñas también pueden contener caracteres de dos puntos : Para extraerlo correctamente de b64auth , puede usar esto.

// 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)

Por otro lado, si solo usa uno o muy pocos inicios de sesión, este es el mínimo indispensable que necesita:
(no es necesario analizar las credenciales)

//btoa(''yourlogin:yourpassword'') -> "eW91cmxvZ2luOnlvdXJwYXNzd29yZA==" // Verify login and password is correct if (req.headers.authorization !== ''Basic eW91cmxvZ2luOnlvdXJwYXNzd29yZA=='') { // ...send(''Authentication required.'') return }

Por cierto, ¿necesita tener caminos seguros y "públicos"? Considere usar express.router lugar.

var securedRoutes = require(''express'').Router() securedRoutes.use(/* auth-middleware from above */) securedRoutes.get(''path1'', /* ... */) app.use(''/secure'', securedRoutes) app.get(''public'', /* ... */) // example.com/public // no-auth // example.com/secure/path1 // requires auth


TL; DR:

express.basicAuth se ha ido
basic-auth-connect está en desuso
basic-auth no tiene ninguna lógica
http-auth es una exageración
express-basic-auth es lo que quieres

Más información:

Como usa Express, puede usar el middleware express-basic-auth .

Ver los documentos:

Ejemplo:

const app = require(''express'')(); const basicAuth = require(''express-basic-auth''); app.use(basicAuth({ users: { admin: ''supersecret123'' }, challenge: true // <--- needed to actually show the login dialog! }));


Cambié en Express 4.0 la autenticación básica con http-auth , el código es:

var auth = require(''http-auth''); var basic = auth.basic({ realm: "Web." }, function (username, password, callback) { // Custom authentication method. callback(username === "userName" && password === "password"); } ); app.get(''/the_url'', auth.connect(basic), routes.theRoute);


Express ha eliminado esta funcionalidad y ahora recomienda usar la biblioteca de jshttp/basic-auth .

Aquí hay un ejemplo de cómo usar:

var http = require(''http'') var auth = require(''basic-auth'') // Create server var server = http.createServer(function (req, res) { var credentials = auth(req) if (!credentials || credentials.name !== ''aladdin'' || credentials.pass !== ''opensesame'') { res.statusCode = 401 res.setHeader(''WWW-Authenticate'', ''Basic realm="example"'') res.end(''Access denied'') } else { res.end(''Access granted'') } }) // Listen server.listen(3000)

Para enviar una solicitud a esta ruta, debe incluir un encabezado de Autorización formateado para la autenticación básica.

Para enviar primero una solicitud de curl, debe tomar la codificación base64 del name:pass o en este caso aladdin:opensesame que es igual a YWxhZGRpbjpvcGVuc2VzYW1l

Su solicitud de curl se verá así:

curl -H "Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l" http://localhost:3000/


Gran parte del middleware se extrajo del núcleo Express en v4 y se colocó en módulos separados. El módulo básico de autenticación está aquí: https://github.com/expressjs/basic-auth-connect

Tu ejemplo solo necesitaría cambiar a esto:

var basicAuth = require(''basic-auth-connect''); app.use(basicAuth(''username'', ''password''));


Parece haber varios módulos para hacer eso, algunos están en desuso.

Este se ve activo:
jshttp/basic-auth

Aquí hay un ejemplo de uso:

// auth.js var auth = require(''basic-auth''); var admins = { ''[email protected]'': { password: ''pa$$w0rd!'' }, }; module.exports = function(req, res, next) { var user = auth(req); if (!user || !admins[user.name] || admins[user.name].password !== user.pass) { res.set(''WWW-Authenticate'', ''Basic realm="example"''); return res.status(401).send(); } return next(); }; // app.js var auth = require(''./auth''); var express = require(''express''); var app = express(); // ... some not authenticated middlewares app.use(auth); // ... some authenticated middlewares

Asegúrese de poner el middleware de auth en el lugar correcto, cualquier middleware anterior no será autenticado.


Podemos implementar la autorización básica sin necesidad de ningún módulo

//1. var http = require(''http''); //2. var credentials = { userName: "vikas kohli", password: "vikas123" }; var realm = ''Basic Authentication''; //3. function authenticationStatus(resp) { resp.writeHead(401, { ''WWW-Authenticate'': ''Basic realm="'' + realm + ''"'' }); resp.end(''Authorization is needed''); }; //4. var server = http.createServer(function (request, response) { var authentication, loginInfo; //5. if (!request.headers.authorization) { authenticationStatus (response); return; } //6. authentication = request.headers.authorization.replace(/^Basic/, ''''); //7. authentication = (new Buffer(authentication, ''base64'')).toString(''utf8''); //8. loginInfo = authentication.split('':''); //9. if (loginInfo[0] === credentials.userName && loginInfo[1] === credentials.password) { response.end(''Great You are Authenticated...''); // now you call url by commenting the above line and pass the next() function }else{ authenticationStatus (response); } }); server.listen(5050);

Fuente: - http://www.dotnetcurry.com/nodejs/1231/basic-authentication-using-nodejs


basicAuth el código para la basicAuth original para encontrar la respuesta:

app.use(function(req, res, next) { var user = auth(req); if (user === undefined || user[''name''] !== ''username'' || user[''pass''] !== ''password'') { res.statusCode = 401; res.setHeader(''WWW-Authenticate'', ''Basic realm="MyRealmName"''); res.end(''Unauthorized''); } else { next(); } });