如何签署JWT?

时间:2015-02-04 03:52:50

标签: ruby authentication oauth sinatra jwt

我正在尝试保护Sinatra API。

我正在使用ruby-jwt来创建JWT,但我不确切地知道要用它来签名。

我正在尝试使用用户的BCrypt password_digest,但每次调用password_digest时它都会发生变化,当我去验证时,签名无效。

3 个答案:

答案 0 :(得分:3)

使用任何类型的应用程序密钥,而不是用户的bcrypt密码摘要。

例如,使用dot env gem和.env文件,条目如下:

JWT_KEY=YOURSIGNINGKEYGOESHERE

我个人使用简单的随机十六进制字符串生成密钥:

SecureRandom.hex(64)

十六进制字符串只包含0-9和a-f,因此该字符串是URL安全的。

答案 1 :(得分:1)

根据wikipedia,密码学中使用的密钥基本上只是一个打开锁的密钥。密钥应该是一致且可靠的,但不容易复制,就像您在家中使用的密钥一样。

this answer所述,秘密密钥应随机生成。但是,您仍希望保留密钥以在整个应用程序中使用。通过使用来自bcrypt的密码摘要,您实际上使用的是从基本密钥(密码)派生的散列密钥。因为散列是随机的,所以这不是可靠的密钥,正如你所说的那样。

使用SecureRandom.hex(64)的上一个答案是创建初始基本应用程序密钥的好方法。但是,在生产系统中,您应该将其作为配置变量并将其存储,以便在应用程序的多次运行中保持一致使用(例如,在服务器重新启动后,您不应使所有用户的JWT无效)或跨多个分布式服务器This article给出了一个从rails环境变量中提取密钥的示例。

答案 2 :(得分:0)

对于RS256公钥和私钥策略,您可以使用Ruby OpenSSL lib:

生成密钥:

key = OpenSSL::PKey::RSA.new 2048

open 'private_key.pem', 'w' do |io| io.write key.to_pem end
open 'public_key.pem', 'w' do |io| io.write key.public_key.to_pem end

从.pem文件加载密钥以签名令牌:

priv_key = OpenSSL::PKey::RSA.new File.read 'private_key.pem'
token = JWT.encode payload, priv_key, 'RS256'

从.pem文件中加载密钥以验证令牌(为此创建中间件):

      begin
        # env.fetch gets http header
        bearer = env.fetch('HTTP_AUTHORIZATION').slice(7..-1)
        pub_key = OpenSSL::PKey::RSA.new File.read 'public_key.pem'
        payload = JWT.decode bearer, pub_key, true, { algorithm: 'RS256'}

        # access your payload here

        @app.call env
      rescue JWT::DecodeError
        [401, { 'Content-Type' => 'text/plain' }, ['A token must be passed.']]
      rescue JWT::ExpiredSignature
        [403, { 'Content-Type' => 'text/plain' }, ['The token has expired.']]
      rescue JWT::InvalidIssuerError
        [403, { 'Content-Type' => 'text/plain' }, ['The token does not have a valid issuer.']]
      rescue JWT::InvalidIatError
        [403, { 'Content-Type' => 'text/plain' }, ['The token does not have a valid "issued at" time.']]
      end