问题描述
所以我不确定我的问题是否真的适合stackoverflow,但我会试一试,看看我对JWT的了解是否正确还是完全超出了循环范围.
So I am not sure if my question fits in really in stackoverflow or not but I would give it a shot and try to see if my knowledge of JWT is actually correct or am I out of the loop totally.
因此,我创建的是一个服务器API,该API读取从客户端应用发送的POST请求,并返回Bearer Token,该令牌必须能够访问我创建的其余API.
So what I have created is an server API that reads POST requests that is being sent from a client app and that returns Bearer Token which is needed to be able to access rest of the API's that I have created.
到目前为止,如果用户名和密码与登录名匹配,那么我有一个服务器api创建了Bearer令牌.
So far I have a server api that created Bearer token IF the username and password matches the login.
一个简单的POST请求看起来像
A simple POST requests would look like
{'username': 'hello', 'password': 'world'}
所以我要做的是,我从JWT.IO网站创建了一个JWT编码的JWT,其密码如下所示:
so what I have done instead is that I created a JWT encoded from JWT.IO site with a secret code which would look like:
{'username': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImJhcnJ5In0.-TCwkrPr8dq4WqsckaWNG7G2ddn7e97hH0jkQ-1j5Bo',
'password': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwYXNzd29yZCI6ImF1dG9zbmtyIn0.mWvxW4xga_OQMLKxf5zfSP4bSV0KzLPSRpqapU-RbAw'}
但是我的主要问题是,我应该如何处理客户端应用程序->第一个/token请求之间的连接才能获得不记名令牌?
However my main problem is that how should I handle the connection between client app -> first /token request to be able to get bearer token?
似乎我确实需要以某种方式硬编码"客户端应用程序中的用户名和密码才能访问我的API,但是我觉得这不是正确的方法,因为那样一来,您就可以读取网络记录并向服务器发送相同的请求,您将永远获得一个新的Bearer令牌,您可以操纵我的服务器api.
It seems like I do need to somehow "hardcode" the username and password inside the client app to be able to access my API but I feel like this is not the correct way because then you would just be able to read the network logs and send the same requests to the server and you would forever get a new Bearer token which you can manipulate my server api.
我的问题是,我应该怎么做才能不能在客户端应用程序中公开我的用户名和密码,并不能通过我的服务器api进行操作?因为我的服务器所做的是它使用secret解码来自JWT的用户名和密码,并且如果用户名和密码与我的服务器api用户名和密码匹配,则匹配.但是感觉就像通过将我的用户名和密码与已完成编码的JWT令牌公开一样,您仍然可以使用这些值并做您想做的一切?
My question is that what way should I do to not be able to expose my username and password in the client app AND to be able manipulate through my server api? Because what my server does is that it decodes the username and password from JWT with secret and matches if the username and password matches my server api username and password. But it feels like by exposing my username and password with already finished encoded JWT token you would still be able to use those values and do whatever you want?
客户端应用示例:
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)
推荐答案
从您的描述来看,您的用例中的客户端似乎是在代表自己,而不是在代表人类用户.
From your description, it seems the client in your use case is acting on its own behalf and NOT on behalf of a human user.
在这种情况下,适用的OAuth2授予类型称为客户端凭据",其中客户端将授权"标头中的客户端凭据(通常是客户端ID和客户端密钥)发送到授权服务器.然后,授权服务器将共享访问令牌和/或刷新令牌,这些令牌需要存储在客户端的cookie中(通常以JWT的形式),并与每个后续请求一起发送到资源服务器.关于授权"标头的唯一特殊之处在于,它告诉整个HTTP基础结构不要在任何共享的缓存中缓存该值.
In such case, the OAuth2 grant type that is applicable is called "Client Credentials" where the client sends the client credentials (usually a client id and a client secret) in the "Authorization" header to the authorization server. The authorization server will then share an access token and/or refresh token that need to be stored on the client side in a cookie (usually in the form of JWT) and sent along with every subsequent request to the resource server. The only thing special about the "Authorization" header is that it tells the entire HTTP infrasrtucture not to cache the value in any shared cache.
现在,问题是,我们如何存储客户机密.我们应该在客户端中对其进行硬编码吗?当然不是.通常,处理此问题最安全的方法是将其存储在密码保险柜中.通常,保管库将机密,密码和证书存储在防篡改的硬件安全模块(HSM)中. (但是,在没有文件库的情况下,通常也将机密信息以加密形式存储在单独的文件中.)
Now, the question is, how do we store the client secret. Should we hard code it in the client? Certainly not. Usually the most secured way to handle this is to store it in a password Vault. Usually the vault stores the secrets, passwords and certificates in a tamper resistant Hardware Security Module (HSM). (But in the absence of a vault, it is also common to store the secret in encrypted form in a separate file).
唯一需要回答的问题是,客户端如何连接到保险柜.保险柜信任该平台(例如AWS或Kubernetes或任何其他云平台).在这些平台上启动VM或容器时,平台会在容器中注入令牌.然后,应用程序将使用令牌连接Vault,该Vault可以通过平台验证令牌的真实性.
The only question left being answered is, how the client connects to the Vault. The Vault trusts the platform (say the AWS or Kubernetes or any other cloud platform). When the VM or the container is launched in those platforms, a token is injected by the platform in the container. The application will then use the token to connect the Vault which can verify the authenticity of the token with the platform.
这篇关于如何在不暴露的情况下正确发送JWT的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!