- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
以下 python 代码使用 pyjwt
生成有效的 JWT token :
>>> import jwt
>>> payload = {'nested': [{'name': 'me', 'id': '1'}]}
>>> token = jwt.encode(payload, 'secret')
>>> token.decode()
ey[...]ko0Zq_k
pyjwt
还支持从命令行界面调用。但是the docs仅显示带有 =
分隔键值对的示例,而不显示带有嵌套有效负载的示例。
我最好的猜测是:
$ pyjwt --key=secret encode nested=[{name=me, id=1}]
ey[...]0FRW9gyU # not the same token as above :(
这不起作用。是不是根本不支持?
最佳答案
如上所述,您的命令行 token 在解码时返回此 json
对象:
{'nested': '[{name=me,', 'id': '1}]'}
快速深入了解 jwt
包的 __main__.py
可以得到以下小片段:
... snipped
def encode_payload(args):
# Try to encode
if args.key is None:
raise ValueError('Key is required when encoding. See --help for usage.')
# Build payload object to encode
payload = {}
for arg in args.payload:
k, v = arg.split('=', 1)
... some additional handling on v for time, int, float and True/False/None
... snipped
正如您所看到的,有效负载的键和值是直接根据 split('=', 1)
确定的,因此任何内容都会通过第一个 =
在命令行中,后面的键将始终被确定为单个值(之后进行一些转换)。
简而言之,不支持 CLI 中的嵌套 dict
。
不过,好消息是,您可以通过某些方法来解决这些问题:
直接从 Python 的 CLI 运行即兴语句,如下所示:
> python -c "import jwt; print(jwt.encode({'nested':[{'name':'me', 'id':'1'}]}, 'secret').decode('utf-8'))"
# eyJ...Zq_k
并不完全理想,但它可以满足您的需求。
将相同的脚本保存到能够获取参数的 .py 中并在 Python 的 CLI 上执行它:
import sys, jwt
my_json = sys.argv[0]
token = jwt.encode(eval(my_json), 'secret')
print(token.decode('utf-8'))
# run in CLI
> python my_encode.py "{'nested':[{'name':'me', 'id':'1'}]}"
# eyJ...Zq_k
请注意,出于安全考虑,此处使用 eval()
并不理想。这只是我实现它的懒惰方式,因为我不想为参数编写解析器。如果您绝对必须使用 CLI 来实现并且它是公开的,我强烈建议您投入精力更仔细地清理和解析 argv
。
最人为的方法:您可以尝试修改Lib\site-packages\jwt\__main__.py
函数(后果自负)满足您的需要,直到添加官方支持。我要提醒你的是,在考虑弄乱主代码之前,你应该对编写自己的解析感到相当舒服。在我意识到您将遇到的限制之前,我尝试了一些方法:
a.主要的 encode()
方法不会将 list
视为有效的 JSON 对象(但它应该如此)。因此,您必须立即拥有一个类似于字典的字符串来进行操作。
b.如果可能,代码始终强制将数字转换为 int
或 float
。您需要以某种方式转义它或完全改变它处理数字的方式。
我的尝试是这样的:
def func(result, payload):
for arg in payload:
k, v = arg.split('=', 1)
if v.startswith('{') and v.endswith('}'):
result[k] = func({}, v[1:-1])
else:
... the rest of the existing code
但是我很快就遇到了原始参数已经以空格分隔的限制,并假设它是一个 k
, v
对,我需要进一步处理另一个分隔符,例如,
以及处理列表
的能力,而且它可能会变得更困惑。这绝对是可行的,而且效果是立竿见影的,即 CLI 直接从这个 __main__.py
运行,但是这比我目前想要投入的工作量要多,所以我把它留给你能干的手.
克服这些问题以实现您所需的努力可能超出必要,具体取决于您的技能和舒适程度。所以选择你的战斗...如果 CLI 不是绝对必要的,我建议只使用 .py
方法。
关于python - 如何在 pyJWT 中使用列表或字典作为命令行参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53064169/
我是一名优秀的程序员,十分优秀!