如何正确地发送JWT而不被暴露

问题描述 投票:0回答:1

所以我不确定我的问题是否真的适合stackoverflow,但我会试一试,看看我对JWT的了解是否确实正确,或者我是否完全脱离循环。

因此,我创建的是一个服务器API,该API读取从客户端应用发送的POST请求,并返回Bearer Token,这是能够访问我创建的API其余部分所必需的。

到目前为止,如果用户名和密码与登录名匹配,则我有一个服务器api创建了Bearer令牌。

简单的POST请求看起来像

{'username': 'hello', 'password': 'world'}

所以我要做的是,我创建了一个从JWT.IO站点编码的JWT,它的秘密代码如下:

{'username': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImJhcnJ5In0.-TCwkrPr8dq4WqsckaWNG7G2ddn7e97hH0jkQ-1j5Bo',
 'password': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwYXNzd29yZCI6ImF1dG9zbmtyIn0.mWvxW4xga_OQMLKxf5zfSP4bSV0KzLPSRpqapU-RbAw'}

但是我的主要问题是我应该如何处理客户端应用程序之间的连接->第一个/ token请求才能获得不记名令牌?

似乎我确实需要以某种方式对客户端应用程序中的用户名和密码进行“硬编码”才能访问我的API,但我觉得这不是正确的方法,因为那样一来,您就可以读取网络日志并将相同的请求发送到服务器,您将永远获得一个新的Bearer令牌,可以操纵我的服务器api。

我的问题是,我应该怎么做才能不能在客户端应用中公开我的用户名和密码,并不能通过服务器api进行操作?因为我的服务器所做的是它使用secret解码来自JWT的用户名和密码,并且如果用户名和密码与我的服务器api用户名和密码匹配,则匹配。但是感觉就像通过将我的用户名和密码与已完成编码的JWT令牌公开一样,您仍然可以使用这些值并做您想做的一切?

客户端应用程序的示例:

import requests

headers = {
    'accept': 'application/json',
    'Content-Type': 'application/x-www-form-urlencoded',
}

data = {'username': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImJhcnJ5In0.-TCwkrPr8dq4WqsckaWNG7G2ddn7e97hH0jkQ-1j5Bo',
        'password': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwYXNzd29yZCI6ImF1dG9zbmtyIn0.mWvxW4xga_OQMLKxf5zfSP4bSV0KzLPSRpqapU-RbAw'}


response = requests.post('http://127.0.0.1:8000/token', headers=headers, data=data, verify=False)
python security jwt
1个回答
2
投票

从您的描述来看,您的用例中的客户端似乎是在代表自己,而不是在代表人类用户。

在这种情况下,适用的OAuth2授予​​类型称为“客户端凭据”,其中客户端将“授权”标头中的客户端凭据(通常是客户端ID和客户端密钥)发送到授权服务器。然后,授权服务器将共享访问令牌和/或刷新令牌,这些令牌需要存储在客户端的cookie中(通常以JWT的形式),并与每个后续请求一起发送到资源服务器。关于“ Authorization”标头的唯一特殊之处在于,它告诉整个HTTP基础结构不要在任何共享的缓存中缓存该值。

现在,问题是,我们如何存储客户机密。我们应该在客户端中对其进行硬编码吗?当然不是。通常,最安全的方法是将其存储在密码保险柜中。通常,保管库将机密,密码和证书存储在防篡改的硬件安全模块(HSM)中。 (但在没有保险库的情况下,通常也将加密形式的机密存储在单独的文件中。)

剩下的唯一要回答的问题是,客户端如何连接到保险柜。保险柜信任该平台(例如AWS或Kubernetes或任何其他云平台)。在这些平台上启动VM或容器时,平台会在容器中注入令牌。然后,应用程序将使用令牌连接Vault,该Vault可以通过平台验证令牌的真实性。

© www.soinside.com 2019 - 2024. All rights reserved.