为外部api Ruby on Rails生成安全令牌

时间:2018-07-13 10:49:31

标签: ruby encryption jwt ruby-on-rails-5

我必须使用需要以这种方式相互通信的应用程序:

  • 服务1向服务2传达它需要创建一个新用户和该用户的令牌。
  • 服务2验证确实是服务1发出了请求
  • 服务2生成供用户使用的令牌

我不确定验证服务1发出请求的“最佳/更好”方法是什么。 到目前为止,我正在使用JWT gem为用户生成令牌,并且一直在开发中使用它来为Service 1生成密钥。

payload =  {data: 'admin'}
admin_key = JWT.encode(payload,Rails.application.secrets.secret_key_base)

我将密钥交给服务1发送,然后对其进行解码,并检查它是否是我最初发送的内容

def authorize_admin
    payload = request.headers['Authorization']
    raise(ExceptionHandler::MissingToken, Message.missing_token) if payload.blank?
    body = JWT.decode(payload, Rails.application.secrets.secret_key_base)[0].values
    body.include?('admin')
end

这可行,但是我担心这可能不是一个安全的选择,或者有什么替代方法可以改善此问题。 Rails.application.secrets.secret_key_base是我的应用程序所独有的,因此我认为这很适合用于通过JWT加密令牌。

总而言之,我的问题:

  1. 我可以在Rails应用程序中使用什么来验证另一个外部应用程序?
  2. JWT与secret_key_base结合使用是否可以为外部api创建唯一令牌的安全方法?

我浏览了有关JWT的其他文章,但是(我发现)没有一个关于它在Rails应用程序中的使用以及secret_key_base的细节

1 个答案:

答案 0 :(得分:0)

JWT使用密钥对有效负载进行签名,而不是对其进行加密。签名并不是天生的安全性,因为给定输入后,签名将始终返回相同的输出(即,签名的模式开始出现)。为了获得最大的安全性,您可能希望对有效负载选择使用AES-256(或更高版本)进行加密。

在这种情况下,授权标头也将始终相同,因为您要发送使用相同密钥编码的相同有效负载,这意味着我可以使用相同的标头从自己的站点访问服务器2并获得用户和令牌。这取决于服务2的敏感程度,如果每个人都可以使用它创建用户,那么这并不重要。否则,这可能是一个巨大的安全隐患。

两个服务器如何解耦?如果服务2可以与之交互的其他服务数量有限,并且知道它们是什么,则可以使用CORS标头来确保只有服务1可以接收来自服务2的请求。