我正在开发一个 OpenID 消费者库 [ 1 ] 在两个单独的 Web 请求中完成其工作:
- 当用户请求身份验证时,库会从用户提供的 URL 中发现一些信息。
- 当图书馆实际完成身份验证时,在另一个 Web 请求期间使用此信息。
我想要一个关于如何最好地设计用于在两个请求之间保存“发现信息”的库 API 的建议:
我可以要求调用者为这两个调用提供他们自己的 session 对象,库将从中存储和读取自己的对象:
result = openid.request(session, url) # stores discovery in `session` # ... openid.authenticate(session, auth_data) # reads discovery from `session`我不太喜欢它的美学,因为它看起来像一个控制反转:带上你自己的缓冲区,我们会为你使用它。此外,“ session ”不是一个定义明确的接口(interface),可能会暴露一些限制。例如,Django 中的 session 默认情况下只想存储 JSON 可序列化的对象,而表示发现信息的对象属于 json 无法识别的自定义类。
我可以将发现信息返回给调用者,让他们按照他们认为合适的方式进行处理:
result, discovery = openid.request(url) session['openid.discovery'] = discovery # ... openid.authenticate(session['openid.discovery'], auth_data)这使库更干净(无需发明 session key 名称或 session 清理策略),但将此工作移交给调用者。如果调用者是另一个为 Web 框架实现 OpenID 行为的库代码,这可能没问题,但如果调用者是不应为这种簿记工作所困扰的应用程序开发人员,则可能不行。
哪种方法最好(对于“最佳”的任何主观定义)?还有一个吗?
请您参考如下方法:
第二种方法肯定更干净,因为:
- 正常的返回值总是比“out”参数好
- 它不限制你的 session 对象的格式(事实上,可能根本就没有明确的 session 对象)
