Я создаю API и пытаюсь выяснить аутентификацию в нескольких контекстах.
Сеансы и аутентификация пароля
API должен обслуживать клиентские приложения, которые мы создаем и развертываем, и обрабатывать аутентифицированные запросы с использованием пароля. Не стоит посылать пароль с каждым запросом, поэтому имеет смысл сначала нажать конечную точку входа и получить идентификатор сеанса. Webapp, о котором идет речь, написан в AngularJS и должен отслеживать свой собственный сеанс в локальном хранилище, чтобы уменьшить захват сеанса и удалить зависимость от файлов cookie для отслеживания сеансов.
Webapp должен будет отправить идентификатор сеанса с каждым запросом и в настоящее время делает это в теле запроса. Этот фрагмент довольно легко и тесно связан с API. Я бы скорее передал всю информацию об аутентификации одним способом - через заголовок, предпочтительно - вместо нескольких полей, расположенных по всему телу запроса, url и заголовкам.
Хранилище сеансов
Redis - это, конечно, удивительно. Хранилище сеансов является простым и автоматически собирает мусор. К сожалению, сеансов в redis сложно управлять: я не могу легко отменить все сеансы для данного пользователя. Добавление этой возможности путем хранения сеансов в истинной redis-datastructure вместо глобального пространства ключей устраняет возможность добавления TTL с ключевыми ключами. Мое текущее решение состоит в том, чтобы хранить список сеансов в пользовательской коллекции MongoDB и мусор-сбор истекших сеансов активности сеанса (например, вход/выход из системы).
Сессии хранятся в redis с connect-redis, но по мере их отправки с каждым запросом не включены в файлы cookie. На данный момент у меня есть небольшая часть промежуточного программного обеспечения, которая выводит идентификатор сеанса из тела запроса и помещает его в объект req.cookies
.
var express = require('express');
var RedisStore = require('connect-redis')(require('connect'));
var app = express();
app.use(function(req, res, next) {
req.cookies = {session: req.body.session};
});
app.use(express.session({
store: new RedisStore({
client: redisClient,
prefix: 'session:'
}),
key: 'session',
secret: 'all mine'
});
Этот подход работает отлично, за исключением того, что express.session
заканчивает настройку файла cookie, когда экспресс отвечает, и что это не желаемое поведение.
Как настроить это правильно в контексте Express?
Ключи API
Наш API также должен поддерживать ключи API для сторонних приложений, чтобы получить ограниченный и контролируемый доступ к нашей системе. Самый распространенный механизм, который я знаю для этого, - это распространять ключи API для заинтересованных разработчиков, а разработчик передает ключ API как часть запроса. Это приводит к той же дилемме, что и проверка подлинности на сеанс/пароль: каждый API ожидает ключ API в другой части запроса, от тела до URL-адреса в заголовках.
Расширение и открытые стандарты
В то время как мы не планируем поддерживать стандарты Open аутентификации, такие как OpenAuth и OpenID при первоначальном выпуске, мы хотим создать структуру, в которой добавление указанных стандартов является простым. Частью этого может быть унификация того, как авторизационные полномочия авторизации передаются API, как с аутентификацией сеанса/пароля и аутентификации API Key.
Другой вопрос спрашивает, является ли настройка заголовка HTTP Authorization
хорошей идеей или если пользовательский заголовок - лучшая идея.
Поддержка CRUD
Чтобы поддерживать парадигму CRUD для API RESTful, имеет смысл не предоставлять информацию об аутентификации в теле, поскольку это ограничивало бы все запросы API для запросов POST, тогда как CRUD рекомендует использовать различные методы HTTP.
TL;DR
Две вещи:
- Как мы можем использовать модуль, например connect-redis без использования сеансов на основе файлов cookie.
- Как нам настроить информацию аутентификации для максимальной гибкости и функциональной совместимости?