首页 > 解决方案 > 为外部 api Ruby on Rails 生成安全令牌

问题描述

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

我不确定验证服务 1 是否发出请求的“最佳/更好”方式是什么。截至目前,我正在使用 JWT gem 为用户生成令牌,并一直在开发中使用它为服务 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 一起使用的细节

标签: rubyencryptionjwtruby-on-rails-5

解决方案


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

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

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


推荐阅读