Как хранить токен, созданный RESTful API?

Я создал API, который генерирует токен аутентификации для пользователей, которые входят в систему. В это время у меня также есть клиентское приложение, написанное в Node.JS.
Когда я делаю запрос с учетными данными пользователя из клиентского приложения в API, я получаю токен аутентификации: как его сохранить в клиентском приложении? Я не должен запрашивать токен каждый раз, когда хочу сделать запрос на API, правильно?
Я думал о том, чтобы поставить токен в Cookie, но я не думаю, что это лучшее решение. Что бы вы порекомендовали?

Ответ 1

После успешного входа в систему уникальная одноразовая маркер должна быть создана на стороне сервера и храниться в базе данных с идентификатором пользователя и меткой времени. Вы сохраняете токен на стороне клиента cookie. Затем вы передаете токен каждому последующему вызову API. Затем сервер должен проверить, что токен действителен (т.е. Не истек, скажем, выдается или обновляется меньше, чем говорят 30 минут назад). Если это действительно так, вы можете получить данные пользователя, хранящиеся на этом маркере, и выполнить любые функциональные возможности бэкэнд (при аутентификации пользователя). Затем вы обновляете метку времени для этого токена (обновляйте сеанс так, как вы хотите, чтобы время входа в систему отключилось после того, как через 30 минут не было взаимодействия с пользователем). Если токен истек или не существует при вызове API, переадресовывайтесь на страницу входа.

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

Ответ 2

Я думаю, что эта ссылка может вам помочь:

Фактически, у вас должен быть токен с датой истечения срока действия, поэтому вам не нужно каждый раз получать новый токен перед отправкой запроса. Когда токен истекает, вам просто нужно получить новый из "токена обновления" службы.

Что касается вопроса о том, как хранить токен в клиентском приложении, я думаю, что вы можете сохранить его в памяти (карта или встроенная база данных).

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

Надеюсь, это поможет вам. Thierry

Ответ 3

Мы работаем над приложением, которое использует очень похожий подход. Клиентское приложение представляет собой статическое одностраничное одностраничное приложение HTML5/JS (без генерации на стороне сервера) и общается с сервером API.

Лучший подход - хранить токен сеанса в памяти, то есть внутри переменной в JS-коде. Если ваше клиентское приложение является одной страницей, это не должно быть проблемой.
В дополнение к этому мы также сохраняем токен сеанса в sessionStorage, чтобы сохранить его, если пользователь обновит страницу. Чтобы сохранить токен при создании новых вкладок (sessionStorage специфичен для окна браузера), мы также храним его в localStorage, когда страница закрывается, вместе с счетчиком открытых вкладок (когда все вкладки приложения закрыты, мы удалите токен.

// Handle page reloads using sessionStorage
var sess = sessionStorage.getItem('session-token')
if(sess && sess !== 'null') { // Sometimes empty values are a string "null"
    localStorage.setItem('session-token', sess)
}

// Set a counter to check when all pages/tabs of the application are closed
var counter = parseInt(localStorage.getItem('session-counter') || 0, 10)
counter++
localStorage.setItem('session-counter', counter)

// Event fired when the page/tab is closing
window.onbeforeunload = function() {
    var counter = parseInt(localStorage.getItem('session-counter') || 0, 10)
    counter--
    localStorage.setItem('session-counter', counter)

    // All pages are closed: remove the session token
    if(counter <= 0) {
        // Handle page reloads using sessionStorage
        sessionStorage.setItem('session-token', localStorage.getItem('session-token'))

        localStorage.removeItem('session-token')
    }
}

Дополнительные сведения о localStorage и sessionStorage: https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API

Почему не куки? Файлы cookie плохие по двум причинам: 1. Они, как правило, более настойчивы, они разделяются между окнами и вкладками браузера, и они могут сохраняться даже после закрытия браузера. 2. Самое главное, однако, по спецификациям HTTP они должны быть отправлены на веб-сервер каждый раз, когда делается запрос. Если вы разрабатываете приложение, в котором клиент полностью отделен от сервера API, вы не хотите, чтобы клиентский сервер видел (или записывал!) Токен сеанса в любом случае.

Некоторые дополнительные советы:

  • Истекшие токены сеанса. Вы можете добиться этого, сохранив токены сеанса в базе данных на сервере и проверив их при каждом запросе и/или "подписав" их (добавив метку времени в токен в виде простого текста, а затем добавив подписанную часть, например хеш-память HMAC, с меткой времени, закодированной секретным ключом, который вы только знаете).
  • Токены могут повторно использоваться столько раз в течение их жизни. Однако через определенное количество секунд вы можете захотеть, чтобы ваш сервер обновил токены, аннулировал старый и отправил клиенту новый токен.