Почему заголовок «expiry» не обновляется при каждом новом запросе к приложению Ruby on Rails? - PullRequest
0 голосов
/ 15 апреля 2019

Я использую модуль Devise :timeoutable для истечения сеанса через некоторое время бездействия. Время ожидания сбрасывается при каждом новом запросе, поэтому дата окончания сеанса смещается. Но это просто не отражено в заголовке expiry, отправляемом в ответ клиенту.

Я заметил, что заголовок ответа expiry является постоянным для всех XHR, которые я отправляю на сервер. Даже после обновления страницы заголовок expiry не обновляется. Другими словами, значение заголовка является правильным только для самого первого запроса, который я отправляю после входа в систему, и затем он остается постоянным.

Нет соответствующего кода для демонстрации, поскольку Devise добавляет заголовки аутентификации к каждому ответу из коробки.

Вот как выглядят заголовки ответа :

access-token: qK5XalnvENIXJDHGCKJ5_A
Cache-Control: no-cache
client: c-4_msWmyUFD7PwD7fPW5Q
Connection: keep-alive
Content-Encoding: gzip
Content-Type: application/json; charset=utf-8
Date: Mon, 15 Apr 2019 15:52:32 GMT
expiry: 1556548396
Server: nginx
token-type: Bearer
Transfer-Encoding: chunked
uid: user@email.com
Vary: Origin
X-Request-Id: 2fa70ebf-dcf2-4680-8c25-68d7b5e12b1b
X-Runtime: 0.021004

И заголовки запроса (если применимо):

GET /api/user/context HTTP/1.1
Host: qa.whiz.ai:9060
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
access-token: qK5XalnvENIXJDHGCKJ5_A
client: c-4_msWmyUFD7PwD7fPW5Q
Accept: application/json, text/plain, */*
expiry: 1556548396
uid: user@email.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36
token-type: Bearer
Referer: https://my-page.example.com/
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,uk-UA;q=0.8,uk;q=0.7,ru-UA;q=0.6,ru;q=0.5
Cookie: ...

Я пытался удалить expiry из заголовков запроса, но это не имеет никакого эффекта.

Это ожидаемое поведение? Разве Devise не должен отправлять фактическое значение в этом заголовке из коробки?

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

1 Ответ

1 голос
/ 15 апреля 2019

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

Расписание хранит last_request_at в сеансе (по умолчанию это хранилище cookie).

Вы можете получить значение с помощью:

ENV['warden'].session(scope)['last_request_at']

Где scope основано на названии вашей модели.

Из источника :

Warden::Manager.after_set_user do |record, warden, options|
  scope = options[:scope]
  env   = warden.request.env

  if record && record.respond_to?(:timedout?) && warden.authenticated?(scope) &&
     options[:store] != false && !env['devise.skip_timeoutable']
    last_request_at = warden.session(scope)['last_request_at']

    if last_request_at.is_a? Integer
      last_request_at = Time.at(last_request_at).utc
    elsif last_request_at.is_a? String
      last_request_at = Time.parse(last_request_at)
    end

    proxy = Devise::Hooks::Proxy.new(warden)

    if record.timedout?(last_request_at) &&
        !env['devise.skip_timeout'] &&
        !proxy.remember_me_is_active?(record)
      Devise.sign_out_all_scopes ? proxy.sign_out : proxy.sign_out(scope)
      throw :warden, scope: scope, message: :timeout
    end

    unless env['devise.skip_trackable']
      warden.session(scope)['last_request_at'] = Time.now.utc.to_i
    end
  end
end

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

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