Как выйти из basicAuth (Express)

Я пытаюсь настроить веб-сервер с помощью express. Чтобы получить доступ к этому серверу, пользователи должны пройти аутентификацию, и для этого я использую промежуточное ПО basicAuth(), предоставляемое Express. Он отлично работает, за исключением того, что я не знаю, как выйти из системы после входа в систему! Мне нужно закрыть мой браузер, чтобы отключиться, но вместо этого я хотел бы иметь страницу "отключить", которая будет перенаправляться на страницу "входа" (эта с уродливой формой, используемой для входа...).

Есть ли у кого-нибудь идеи?

Спасибо за аванс

PS: Я прошу прощения за мой жалкий английский:)

Ответ 1

Express 'basicAuth использует базовую аутентификацию HTTP, для реализации которой не нужны HTML-страницы, файлы cookie и идентификаторы сеансов. Его основные недостатки не являются безопасными и, что касается нашей озабоченности, в спецификации нет механизма для того, чтобы сервер дал команду выйти из браузера.

express.basicAuth() требует require (blah-blah/connect/lib/utils).unauthorized(), который отправляет статус 401 с заголовком 'WWW-Authenticate: Basic realm = "..." '. Браузер обрабатывает окно проверки подлинности, а и далее отправляет заголовок, например "Авторизация: Базовый YmFzaWM6YmFzaWM =", который содержит имя пользователя и пароль.

(express.basicAuth не безопасен, особенно по HTTP, потому что вы можете получить имя пользователя: пароль с помощью

new Buffer('YmFzaWM6YmFzaWM=' , 'base64').toString() 

который дает базовый: базовый в этом случае.)

Наша проблема заключается в том, что спецификация HTTP не предоставляет способ остановить отправку этого заголовка. Обходной путь для HTTPS заключается в перенаправлении пользователя на URL-адрес в том же домене с неправильными учетными данными.

Обходной путь HTTP, который я использую для Express V3, можно использовать с app.use(express.basicAuth(...)). Я считаю, что это проще в использовании, чем другие решения, требующие вызова промежуточного программного обеспечения на каждом защищенном маршруте, например. app.get('/secure', checkAuth, function (req, res) {...}).

Вот рабочий пример.

var express = require('express'),
    http = require('http'),
    app = express();

app.use(express.favicon()); // prevent interference during test
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({ secret: 'winter is coming' }));

app.use(function (req, res, next) {
  if (!req.session.authStatus || 'loggedOut' === req.session.authStatus) {
    req.session.authStatus = 'loggingIn';

    // cause Express to issue 401 status so browser asks for authentication
    req.user = false;
    req.remoteUser = false;
    if (req.headers && req.headers.authorization) { delete req.headers.authorization; }
  }
  next();
});
app.use(express.basicAuth(function(user, pass, callback) {
  callback(null, user === 'basic' && pass === 'basic');
}, '***** Enter user= basic & password= basic'));
app.use(function (req, res, next) {
  req.session.authStatus = 'loggedIn';
  next();
});

app.use(app.router);
app.get('/secure', function (req, res) {
  res.send([
    'You are on a secured page.',
    '<br>',
    '<a href="./secure">Refresh this page without having to log in again.</a>',
    '&lt;br/>',
    '<a href="./logout">Log out.</a>'
  ].join(''));
});
app.get('/logout', function (req, res) {
  delete req.session.authStatus;
  res.send([
    'You are now logged out.',
    '&lt;br/>',
    '<a href="./secure">Return to the secure page. You will have to log in again.</a>',
  ].join(''));
});

http.createServer(app).listen(3000, function(){
  console.log('Express server listening on port 3000. Point browser to route /secure');
});

P.S. Ваш английский отличный.

Ответ 2

Для express.js 4 и basicAuth вы можете использовать этот метод:

app.get('/logout', function (req, res) {
    res.set('WWW-Authenticate', 'Basic realm=Authorization Required');
    return res.sendStatus(401);
});

Ответ 3

Добавляя к wyllman, код 401 является Unauthorized. Вы можете просто ответить с помощью res.status(401).send('Logged out')

или же

app.get('/logout', function (req, res) {
    res.status(401).send('Logged out')
    //or res.status(401).end() to force the user to log in on next visit
});