简单而灵活的Python OAuth 2.0设备流认证
项目描述
loctocat
loctocat将简单而灵活的OAuth 2.0设备流认证引入Python。它具有内置的asyncio支持,并为流行的服务预定义了认证器。此外,它完全符合RFC 8628,使其与任何正确实现标准的OAuth2支持服务兼容。
安装
pip install loctocat
基本用法
Authenticator
类
每个认证流程都从loctocat的Authenticator
类开始。
from loctocat import Authenticator
authenticator = Authenticator(
client_id="your_client_id",
auth_url="https://example.com/oauth2/authorize",
token_url="https://example.com/oauth2/token",
scopes=["list", "of", "scopes"],
)
很简单——只需用您的客户端ID、授权URL(您将在其中获取设备和用户代码)、令牌URL(您将在其中轮询授权服务器以获取访问令牌)和任何您需要的范围列表实例化该类。
一旦您有了Authenticator
,获取访问令牌就像这样简单
token = authenticator.authenticate()
哇。这很简单。
Authenticator.authenticate()
将按顺序
- 从授权服务器获取设备和用户代码
- 提示用户访问验证URL并输入用户代码
- 轮询授权服务器以获取访问令牌
- 将访问令牌作为字符串返回
这是使用Authenticator
与GitHub进行认证的示例
# https://githubdocs.cn/en/developers/apps/building-oauth-apps/authorizing-oauth-apps#device-flow
from loctocat import Authenticator
authenticator = Authenticator(
client_id="github_client_id", # Replace this with your app's actual client ID, obviously.
auth_url="https://github.com/login/device/code",
token_url="https://github.com/login/oauth/access_token",
scopes=["repo"], # https://githubdocs.cn/en/developers/apps/building-oauth-apps/scopes-for-oauth-apps
)
token = authenticator.authenticate()
就像我说的那样,很简单。除非您正在构建异步应用程序,在这种情况下,这根本不起作用,因为Authenticator.authenticate()
是一个阻塞调用。幸运的是,loctocat已经为您解决了这个问题。
AsyncAuthenticator
类
AsyncAuthenticator
是 Authenticator
的一个子类,其功能完全相同,只是所有方法都是异步的(因此必须使用 await
来调用)。以下是一个 AsyncAuthenticator
的使用示例
from loctocat import AsyncAuthenticator
authenticator = AsyncAuthenticator(
client_id="your_client_id",
auth_url="https://example.com/oauth2/authorize",
token_url="https://example.com/oauth2/token",
scopes=["list", "of", "scopes"],
)
token = await authenticator.authenticate()
哇。这很简单。
AsyncAuthenticator.authenticate()
将——等等,我好像有似曾相识的感觉。
高级用法
也许 Authenticator.authenticate()
对于你来说太简单了。也许你更愿意,我不知道,自己处理用户界面的身份验证提示,或者控制 loctocat 开始轮询访问令牌的时间。幸运的是,loctocat 已经为你考虑到了。
(请注意,AsyncAuthenticator
是 Authenticator
的一个子类,并继承其所有方法和属性。)
Authenticator.ping()
Authenticator.ping()
从授权服务器请求设备和用户代码,返回一个类似这样的 LoctocatAuthInfo
对象
class LoctocatAuthInfo:
device_code: str
user_code: str
verification_uri: str
expires_in: int
interval: int
非常直观。你可以用这些信息做任何你想做的事情(除了更改它们——LoctocatAuthInfo
的属性是只读的)。例如,你可以使用包含用户代码和验证 URI 的自定义文本提示用户
auth_info = authenticator.ping()
print(f"Check it out, yo! This is some epic text telling YOU to go {auth_info.verification_uri} and enter {auth_info.user_code}! Swag!")
Authenticator.poll()
Authenticator.poll()
轮询授权服务器以获取访问令牌,并将其作为字符串返回。你不需要将 Authenticator.ping()
返回的 LoctocatAuthInfo
对象传递给 Authenticator.poll()
——授权信息会自动由 Authenticator
记忆。你只需调用该方法即可
# Authenticator.ping() must have been called on the Authenticator object already or this will not work.
token = authenticator.poll()
哇。这很简单。
(有趣的事实:Authenticator.authenticate()
只是 ping()
和 poll()
的包装器。)
专业用法
也许 高级用法 对于你来说还不够高级。也许你正在使用一个需要超出 Authenticator
定义参数的授权服务器。也许你想要自定义 Authenticator.authenticate()
显示的提示和信息,而无需使用 Authenticator.ping()
和 Authenticator.poll()
。也许 loctocat 为你喜欢的服务提供了一个预定义的验证器,你想使用它。不幸的是,loctocat 并没有涵盖这些。
...
好吧,实际上 loctocat 确实为你考虑到了,但这些是 loctocat 未完成的文档网站的内容。重点是未完成。它还没有完成。
幸运的是,loctocat 已经为你考虑到了。loctocat 是一个相当小的库,它的公共模块和类都在源代码中有适当的文档,因此你可以通过示例学习,并四处看看。
或者你可以等到我完成文档网站。我不是你的妈妈。
常见问题解答
也许你对 loctocat 有一些问题,这些问题在本 README 的其他部分没有解答。也许你只是想看我自我对话,大概两段。幸运的是,loctocat 已经为你考虑到了。
问:loctowhat 现在怎么办
答:锁 + Octocat。loctocat 是由于我需要一个实现 GitHub OAuth 2.0 设备流身份验证的 Python 库而产生的。
问:我确信我可以使用 requests-oauthlib 或 [INSERT OAUTH LIBRARY HERE] 很好地完成这个任务
答:当然可以。事实上,loctocat 在底层使用 requests 和 oauthlib。所以让我们放下 loctocat,一起用 requests 和 oauthlib 编写一个用于通过 GitHub 进行身份验证的函数吧!
import time
import requests
from oauthlib.oauth2 import DeviceClient
def authenticate_with_github(client_id: str, scopes: list[str]) -> str:
auth_url = "https://github.com/login/device/code"
token_url = "https://github.com/login/oauth/access_token"
client = DeviceClient(client_id=client_id, scope=scopes)
ping_uri = client.prepare_request_uri(auth_url)
response = requests.post(ping_uri, headers={"Accept": "application/json"}).json()
poll_uri = client.prepare_request_uri(token_url, code=response["device_code"])
while True:
response = requests.post(poll_uri, headers={"Accept": "application/json"}).json()
if "error" in response:
if response["error"] in ["authorization_pending", "slow_down"]:
time.sleep(response["interval"])
continue
else:
raise RuntimeError(response["error"])
else:
return response["access_token"]
该死的,那个盘子能煮!
现在让我们用 loctocat 做同样的事情。
from loctocat.predefined import GitHubAuthenticator
def authenticate_with_github(client_id: str, scopes: list[str]) -> str:
authenticator = GitHubAuthenticator(client_id=client_id, scopes=scopes)
return authenticator.authenticate()
# "Hey, that's cheating!" Fine, let's do it the hard way.
from loctocat import Authenticator
def authenticate_with_github(client_id: str, scopes: list[str]) -> str:
authenticator = Authenticator(
client_id=client_id,
auth_url="https://github.com/login/device/code",
token_url="https://github.com/login/oauth/access_token",
scopes=scopes
)
return authenticator.authenticate()
哇。这很简单。
我制作 loctocat 的部分原因是因为没有其他库能够像 loctocat 一样完成这项任务,而且完成得不好。第一个例子很糟糕。第二个例子很棒。案例结束。
问:loctocat 无法与 [INSERT SERVICE HERE] 一起工作,我非常沮丧 AAAAGGGGGGHHHHH
答:loctocat 与 OAuth 2.0 设备授权标准兼容,因此可能是服务的问题。请确保该服务确实支持设备流程,并且通常与 RFC 8628 兼容。如果你确定 loctocat 是问题所在,请 打开一个问题。
问:哦我的天哪,谢谢你,我一直在寻找这样的库,你不知道我有多高兴
欢迎!😄
许可证
在开发者必须格外小心,避免侵犯他人知识产权的时代,您一定希望一个如此出色的库能够以宽松的许可协议提供。幸运的是,loctocat为您提供了保障。
loctocat遵循MIT许可协议。
项目详情
下载文件
下载适合您平台的文件。如果您不确定该选择哪个,请了解更多关于安装包的信息。
源代码分发
构建分发
loctocat-1.0.3.tar.gz的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | ddb1131c5d8c3564f9f3eda074413c70fa82c0fd3dcb6a15401d0ffea980af48 |
|
MD5 | d5b6f8196b8d3ba5e039d2ce2a80b90a |
|
BLAKE2b-256 | ebb38adb71fe77384c22851c73f04ee4951ea7f45a4762da818d90dbeffc5ebc |
loctocat-1.0.3-py3-none-any.whl的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 903285c98ad3b806735a5b5dca2c65c084caffb8e5ffdb8817b4371de47633e0 |
|
MD5 | 823c808cfe13e3c7c6fb0786458502f5 |
|
BLAKE2b-256 | 9e384b628515c740dd31b32f7704a1d69392b19f2e424068eec705ffbefa6314 |