【问题标题】:JWT expire token on ruby on railsJWT 在 ruby​​ on rails 上过期令牌
【发布时间】:2016-11-19 16:10:04
【问题描述】:

我正在尝试将过期时间设置为这样的 jwt 令牌:

class JsonWebToken
  def self.encode(payload)
    payload[:exp] = (2).minutes.from_now.to_i #expire in 2 minutes
    JWT.encode(payload, Rails.application.secrets.secret_key_base)
  end

  def self.decode(token)
    return HashWithIndifferentAccess.new(JWT.decode(token, Rails.application.secrets.secret_key_base)[0])
  rescue
    nil
  end
end

但是当我尝试访问 url 时,令牌始终有效。此外,如果我解码令牌,我永远不会得到 exp 键:哈希值。

任何建议

更新

我正在使用jwt gem

这就是我验证用户的方式。

def authenticate_user
    user = User.find_for_database_authentication(email: params[:email])
    if user.valid_password?(params[:password])
      render json: payload(user)
    else
      render json: {errors: ['Invalid Username/Password']}, status: :unauthorized
    end
  end

  private

  def payload(user)
    return nil unless user and user.id
    {
      auth_token: JsonWebToken.encode({user_id: user.id}),
      user: {id: user.id, email: user.email}
    }
  end

使用 curl 的示例:

curl -X POST -d email="a@a.com" -d password="changeme" http://localhost:3000/auth_user

这个卷曲返回:

{"auth_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxfQ.wPPX7T6WJ5K8ucjZF_l8-9mG7IzabcusLeWw1UOhhTM","user":{"id":1,"email":"a@a.com"}}

然后在我的 Rails 控制台上:

JWT.decode("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxfQ.wPPX7T6WJ5K8ucjZF_l8-9mG7IzabcusLeWw1UOhhTM", Rails.application.secrets.secret_key_base)

然后得到:

[{"user_id"=>1}, {"typ"=>"JWT", "alg"=>"HS256"}]

您可以看到令牌始终有效,即使我在此行设置了过期时间:

def self.encode(payload)
    payload[:exp] = (2).minutes.from_now.to_i #expire in 2 minutes <<--- This one
    JWT.encode(payload, Rails.application.secrets.secret_key_base)
  end

【问题讨论】:

  • 您使用的是什么 JWT gem?您能否分享一个创建令牌然后对其进行解码并且过期无效的最小示例? (例如,你可以使用上面的类。)
  • @smarx 刚刚为您更新了我的问题。提前致谢
  • 您还没有分享一个显示问题的最小示例。例如,某处有代码解析出 Authorization 标头并(大概?)解码 JWT 并应该拒绝带有无效令牌的请求,但我在您共享的代码中看不到任何类似的东西。我所能做的就是说 JWT gem 似乎没有被破坏,所以你的代码中的问题出在其他地方。
  • @smarx 请看我的 curl 示例。您的代码有效,但我不明白为什么我的代码无效
  • 我的假设:这实际上不是您为创建令牌而运行的代码。尝试添加一些日志记录?

标签: ruby-on-rails ruby token jwt


【解决方案1】:

这是一个显示 JWT gem 工作正常的简单测试:

require 'JWT'

class JsonWebToken
  def self.encode(payload, expiration)
    payload[:exp] = expiration
    JWT.encode(payload, 'SECRET')
  end

  def self.decode(token)
    return JWT.decode(token, 'SECRET')[0]
  rescue
    'FAILED'
  end
end

# expire 2 minutes from now
token = JsonWebToken.encode({ :hello => 'world' }, Time.now.to_i + 120)
puts token # eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJoZWxsbyI6IndvcmxkIiwiZXhwIjoxNDY4Njg3OTc1fQ.NhIsdEa0Q7Wl5Dx6kyJvSZY6E8ViJ5Kooo7rKr2OBPg
puts JsonWebToken.decode(token) # {"hello"=>"world", "exp"=>1468687975}

# expire 2 minutes ago
token = JsonWebToken.encode({ :hello => 'world' }, Time.now.to_i - 120)
puts token # eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJoZWxsbyI6IndvcmxkIiwiZXhwIjoxNDY4Njg3NzM1fQ.kDD_WWN3ZTTdFXQvYEgm1CgDaE1mEZxjMvQkQEq4HX8
puts JsonWebToken.decode(token) # FAILED

【讨论】:

  • 感谢您的帮助,但我忘记重启服务器了,这是我的问题。
  • 如预期的那样。 :-) “我的假设:这实际上不是您为创建令牌而运行的代码。”
  • @smarx 如何在用户注销时重置令牌?
猜你喜欢
  • 2017-06-11
  • 1970-01-01
  • 2017-03-04
  • 2019-07-04
  • 2018-06-19
  • 2019-08-08
  • 1970-01-01
  • 1970-01-01
  • 2021-03-19
相关资源
最近更新 更多