Предложение по Api Access с Express -Gateway и аутентификации пользователя с JWT - PullRequest
1 голос
/ 29 января 2020

У меня есть сервер в Express, который предоставляет некоторые API для веб-приложения. Я ищу хороший способ управления как конечными пользователями, так и сторонними пользователями.

Прямо сейчас, когда пользователь регистрируется по электронной почте и паролю, сервер генерирует JWT, связанный с этим пользователем.

function createToken(user, role) {
    var usr = {
        role: role,      // admin | customer | shop
        email: user.email,
        name: user.name
    };

    var expires = (Date.now() / 1000) + 60 * 60 * 24 * 365; // 1 year
    var nbf = Date.now() / 1000;
    usr['nbf'] = nbf;
    usr['exp'] = expires;
    var token = jwts.encode(usr, process.env.SECRET);
    return token;
}

Когда Web-клиент получает этот токен, он сохраняет токен в cookie / web_storage и использует его для каждого вызова API на сервере, а также для автоматического входа в систему. Маркер также содержит role, поэтому, когда сервер получает запрос, он знает, может ли этот пользователь / роль получить доступ к запрашиваемому маршруту / ресурсу.

function checkToken(token, api_name) {
    // verifies secret and checks exp
    jwt.verify(token, process.env.SECRET,
        function (err, decoded) {
            if (err) { throw { msg: "token expired or not authenticated", code: errors.ERR_NOT_AUTH }; }
            else {
                var role = decoded['role'];
                return does_role_can_access_api(role, api_name); // true or false             
            }
    });
}

Теперь некоторые сторонние организации хотят получить доступ к некоторые моих API. Я хочу создать Express -Gateway для создания API-ключей для приложений, которые хотят использовать мой сервер, и сохранить существующую аутентификацию JWT для отдельных пользователей.

Так что у меня будет

 |----------------|
 |   my Web-App   |
 |----------------|----> |------------|            |------------|
                         |   Express  |            | my Server  |
                         |   Gateway  |----------> |    APIs    |
 |----------------|----> |------------|            |------------|
 |    3rd party   |
 |----------------|
  • Мое веб-приложение должно иметь доступ ко всем API, потому что мое веб-приложение используют admin с (как и я) и наши пользователи (customers и shops).
  • Сторонние приложения должны иметь доступ только к некоторым API, так как они будут только customers и shops.

Итак, я хочу сделать что-то вроде этого:

 |----------------|
 |   my Web-App   |
 |     scopes:    |
 | [admin, user]  |
 |                |
 |----------------|----> |------------|            |------------|
                         |   Express  |            | my Server  |
                         |   Gateway  |----------> |    APIs    |
 |----------------|----> |------------|            |------------|
 |    3rd party   |
 |    scopes:     |
 |     [user]     |
 |----------------|

В конце у моего веб-приложения будет ApiKey со всеми областями действия, а у сторонних ApiKeys будет просто user scope, так что я могу фильтровать маршруты по этому. Одиночные реальные пользователи, независимо от используемого приложения, будут использовать токен JWT для входа и выполнения запросов.

Таким образом, каждый запрос будет иметь ApiKey (в зависимости от используемого приложения) и токен JWT (для идентификации пользователя):

  • ApiKey будет добавленный в заголовок сторонним сервером,
  • токен JWT будет (извлечен и) добавлен в заголовок web_storage браузера пользователя.

Звучит хорошо ?

1 Ответ

1 голос
/ 21 февраля 2020

Прежде всего, поздравляем вас с вашими усилиями по разработке защищенного приложения, потому что не каждый день мы видим, как разработчики заходят так далеко.

Разъяснение возможных заблуждений

Прежде чем я углублюсь в ваш вопрос Я хотел бы сначала прояснить заблуждение, которое обычно имеют разработчики в отношении того, что против , кто получает доступ к своим бэкэндам. Это подробно обсуждается в этой статье , где мы можем прочитать:

what - это то, что делает запрос к серверу API. Действительно ли это подлинный экземпляр вашего мобильного приложения, или это бот, автоматизированный скрипт или злоумышленник, который вручную ковыряется в вашем API-сервере с помощью такого инструмента, как Postman?

who пользователь мобильного приложения, которое мы можем аутентифицировать, авторизовать и идентифицировать несколькими способами, например, используя OpenID Connect или потоки OAUTH2.

Пока статья находится в контексте мобильного приложения, для понимания Разница между чем и , кто обращается к серверу API, ссылки на mobile app можно заменить на web app. Если у вас есть какие-то сомнения, пожалуйста, go и прочитайте раздел связанной статьи, который также включает в себя диаграмму c, чтобы помочь понять это.

Ваш вопрос

Верно теперь, когда пользователь регистрируется по электронной почте и паролю, сервер генерирует JWT, связанный с этим пользователем.

var expires = (Date.now() / 1000) + 60 * 60 * 24 * 365; // 1 year

Мое веб-приложение должно иметь доступ ко всем API-интерфейсам, поскольку мое веб-приложение используется администраторы (как и я), а также наши пользователи (клиенты и магазины).

Это слишком длинный путь для токена аутентификации, особенно когда вы говорите, что к API обращаются администраторы, но даже для нормальные пользователи это слишком долго.

В зависимости от вашего случая использования, я рекомендую, чтобы они находились в диапазоне минут, поэтому я предлагаю вам переключиться на использование токенов refre sh, которые будут сохранять жетоны доступа недолговечными, пока токены refre sh могут быть долгоживущим, но в диапазоне часов, а не дней, недель или лет.

Refre sh Пример потока токенов:

Graphic for shorten token lifetimes

Источник: Mobile Security Techniques - часть 2

ПРИМЕЧАНИЕ : хотя приведенная выше диаграмма c относится к серии статей, написанных в контексте мобильных API, в них содержится много информации, которая также подходит для API, обслуживающих веб-приложения, и третьи сторонние клиенты.

При использовании этого подхода клиенту в случае сбоя токена краткосрочного доступа потребуется запросить новый, отправив токен refre sh, чтобы получить новый токен доступа. .

Важным моментом здесь является то, что токен refre sh не следует отправлять в браузер, можно отправлять только токен доступа, поэтому ваши сторонние клиенты должны знать об этом, так что не пытайтесь получить доступ к вашему API напрямую из javascript, вместо этого они должны делегировать это своим бэкэндам.

API-ключи и JWT

В конце концов, мое Web-приложение будет иметь ApiKey со всеми возможностями s, в то время как сторонние ApiKeys будут иметь только пользовательскую область, поэтому я могу фильтровать маршруты по этому. Одиночные реальные пользователи, независимо от используемого приложения, будут использовать токен JWT для входа и выполнения запросов. Таким образом, каждый запрос будет иметь ApiKey (на основе используемого приложения) и токен JWT (для идентификации пользователя):

ApiKey будет добавлен в заголовок сторонним сервером, токен JWT будет (извлечено и) добавлено в заголовок web_storage браузера пользователя.

Я не уверен, что вы говорите, что ключ API будет также токеном JWT, но если нет, то я также будет использовать маркер JWT в качестве ключа API, но с областью / ролью, определяемой c для каждого из ваших сторонних клиентов.

Переходя лишнюю милю

Я не отказываюсь включать в любой секретный вопрос, я отвечаю на отличную работу, проделанную фондом OW ASP, и в данном случае наиболее актуальным для вас является Руководство по тестированию веб-безопасности :

Руководство по тестированию веб-безопасности OW ASP включает в себя инфраструктуру тестирования на проникновение «передовой опыт», которую пользователи могут внедрять в своих организациях, и руководство по тестированию на проникновение «низкого уровня», в котором описываются методы тестирования, наиболее распространенные вопросы безопасности веб-приложений и веб-сервисов.

...