适用于 Python 的 Firefox Accounts 客户端库
项目描述
这是用于与 Firefox 帐户生态系统交互的 python 库。
最终,计划为以下功能提供简单的支持:
作为直接的 Firefox 帐户身份验证客户端
成为 FxA OAuth 服务提供商
访问附加服务
通过请求身份验证插件帮助与 Firefox 帐户服务器交互。
但这些都还没有准备好;买者自负。
火狐帐户
目前,基本的 auth-server 操作应该像这样工作:
from fxa.core import Client
client = Client("https://api.accounts.firefox.com")
client.create_account("test@example.com", "MySecretPassword")
session = client.login("test@example.com", "MySecretPassword")
cert = session.sign_certificate(myPublicKey)
session.change_password("MySecretPassword", "ThisIsEvenMoreSecret")
FxA OAuth 依赖者
将身份验证代码与寿命更长的 OAuth 令牌交换:
from fxa.oauth import Client
client = Client()
token = client.trade_code("client-id", "client-secret", "code-1234")
验证 OAuth 令牌:
from fxa.oauth import Client
from fxa.errors import ClientError
client = Client()
try:
profile = client.verify_token("123456...")
except ClientError:
print "Invalid token"
print("User id", profile["user"])
测试电子邮件地址
还有与 restmail.net 的非常基本的集成,以允许使用实时电子邮件地址进行测试。它是这样工作的:
from fxa.core import Client
from fxa.tests.utils import TestEmailAccount
# Create a testing account using an @restmail.net address.
acct = TestEmailAccount()
client = Client("https://api.accounts.firefox.com")
session = client.create_account(acct.email, "MySecretPassword")
# Verify the account using the code from email.
acct.fetch()
for m in acct.messages:
if "x-verify-code" in m["headers"]:
session.verify_email_code(m["headers"]["x-verify-code"])
...
# Destroy the account once you're done with it.
acct.clear()
client.destroy_account(acct.email, "MySecretPassword")
将令牌和断言传递给其他应用程序
PyFxA 提供了一个fxa 客户端,您可以使用它来导出不记名令牌和浏览器 ID 断言。
为现有帐户获取不记名令牌
fxa-client --bearer --auth you@domain.tld \
--account-server https://api.accounts.firefox.com/v1 \
--oauth-server https://oauth.accounts.firefox.com/v1
Please enter a password for you@domain.tld:
# ---- BEARER TOKEN INFO ----
# User: you@domain.tld
# Scopes: profile
# Account: https://api.accounts.firefox.com/v1
# Oauth: https://oauth.accounts.firefox.com/v1
# ---------------------------
export OAUTH_BEARER_TOKEN="3f5106b203c...b728ef93fe29203aad44ee816a45b2f2ff57a6aed7a3"
在舞台上创建一个新帐户 Bearer Token
fxa-client --bearer --create --prefix hello
# ---- BEARER TOKEN INFO ----
# User: hello-89331eba46e970dc1686ba2dc4583fc9@restmail.net
# Scopes: profile
# Account: https://api-accounts.stage.mozaws.net/v1
# Oauth: https://oauth.stage.mozaws.net/v1
# ---------------------------
export OAUTH_BEARER_TOKEN="ecb5285d59b28e6768fe60d76e6994877ffb16d3232c...72bdee05ea8a5"
在舞台上创建一个新帐户 BrowserID 断言
fxa-client --browserid --create --audience https://token.stage.mozaws.net/ --prefix syncto
# ---- BROWSER ID ASSERTION INFO ----
# User: syncto-5bcf63598bf6026a6833035821742d3e@restmail.net
# Audience: https://token.stage.mozaws.net/
# Account: https://api-accounts.stage.mozaws.net/v1
# ------------------------------------
export FXA_BROWSERID_ASSERTION="eyJhbGciOiJSUzI1NiJ9.eyJw......VNKcPu6Uc9Y4pCuGcdM0UwaA"
export FXA_CLIENT_STATE="abaa31cc3b16aaf6759f2cba164a54be"
有请求
在请求中使用 Firefox 帐户 BrowserID
您可以使用FxABrowserIDAuth来构建 BrowserID 断言:
from fxa.core import Client
from fxa.plugins.requests import FxABrowserIDAuth
email = acct.email
password = "MySecretPassword"
raw_resp = requests.get('https://token.services.mozilla.com/1.0/sync/1.5',
auth=FxABrowserIDAuth(email, password,
with_client_state=True))
raw_resp.raise_for_status()
resp = raw_resp.json()
user_id = resp['uid']
在请求中使用 Firefox 帐户持有者令牌
您可以使用FxABearerTokenAuth来构建承载令牌:
from fxa.core import Client
from fxa.plugins.requests import FxABearerTokenAuth
email = acct.email
password = "MySecretPassword"
raw_resp = requests.get('https://profile.accounts.firefox.com/v1/profile',
auth=FxABearerTokenAuth(email, password,
['profile'], client_id))
raw_resp.raise_for_status()
resp = raw_resp.json()
user_id = resp['uid']
使用 HTTPie
将 Firefox 帐户 BrowserID 与 HTTPie 一起使用
您可以使用 PyFxA 提供的 httpie 插件来构建 BrowserID 请求:
BID_WITH_CLIENT_STATE=True \
http GET https://token.services.mozilla.com/1.0/sync/1.5 \
--auth-type=fxa-browserid --auth "email:password" -v
GET /1.0/sync/1.5 HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Authorization: BrowserID eyJhbG..._EqaQ
Connection: keep-alive
Host: token.services.mozilla.com
User-Agent: HTTPie/0.9.2
X-Client-State: 97b945...920fac4d4d5f0dc6...2992
HTTP/1.1 200 OK
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,X-Conditions-Accepted
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Max-Age: 1728000
Connection: keep-alive
Content-Length: 414
Content-Type: application/json; charset=UTF-8
Date: Tue, 21 Jul 2015 10:48:42 GMT
X-Timestamp: 1437475722
{
"api_endpoint": "https://sync-230-us-west-2.sync.services.mozilla.com/1.5/99283757",
"duration": 3600,
"hashalg": "sha256",
"id": "eyJub2RlI....FlYzdiMCIsICJ1aWQiOiAyMDIzODc3NX2Bvj5zv..7S2jRaw__-....eh3hiSVWA==",
"key": "lSw-MvgK....ebu9JsX-yXS70NkiXu....6wWgVzU0Q=",
"uid": 99283757
}
将 Firefox 帐户不记名令牌与 HTTPie 一起使用
您可以使用 PyFxA 提供的 httpie 插件来构建 Bearer 令牌请求:
$ http GET https://profile.accounts.firefox.com/v1/profile \
--auth-type fxa-bearer --auth "email:password" -v
GET /v1/profile HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Authorization: Bearer 98e05e12ba...0d61231e88daf91
Connection: keep-alive
Host: profile.accounts.firefox.com
User-Agent: HTTPie/0.9.2
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 92
Content-Type: application/json; charset=utf-8
Date: Tue, 21 Jul 2015 14:47:32 GMT
Server: nginx
access-control-allow-headers: Authorization, Content-Type, If-None-Match
access-control-allow-methods: GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS
access-control-allow-origin: *
access-control-expose-headers: WWW-Authenticate, Server-Authorization
access-control-max-age: 86400
cache-control: no-cache
content-encoding: gzip
etag: "d1cf22901b3e3be527c06e27689be705bb22a172"
strict-transport-security: max-age=15552000; includeSubdomains
vary: accept-encoding
{
"email": "email@address.com",
"uid": "63b91ca4ec19ad79f320eaf5815d75e9"
}
变更日志
本文档描述了每个过去版本之间的更改。
0.7.7 (2020-07-17)
修复传递给 oauth.Client 构造函数的 JWK 验证不正确,这实际上阻止了调用者设置正确的值,而不是检查他们是否这样做。
0.7.6 (2020-07-10)
添加配置 JWT 访问令牌密钥的固定列表的功能,方法是将它们作为参数传递给oauth.Client()而不是在运行时从服务器获取它们。
修复 JWT 访问令牌类型标头的验证。(谢天谢地,它关闭失败而不是打开失败)。
修复从 JWT 访问令牌获得的范围列表的验证。(谢天谢地,它关闭失败而不是打开失败)。
0.7.5 (2020-07-06)
向login方法添加对reason和verification_method关键字参数的支持。
0.7.4 (2020-06-10)
在授权 OAuth 代码时对状态参数执行更完整的检查。
验证 OAuth 访问令牌时,请尝试将它们作为 JWT 在本地验证,而不是将它们传递到远程验证端点。
0.7.3 (2019-07-26)
允许在兑换授权码时指定ttl 。
0.7.2 (2019-06-03)
对 Python3 兼容性的一些清理;感谢Tomáš Chvátal!
修复了一个错误,可能会在 oauth.Client.get_redirect_url 的结果中意外引入多个斜杠。
0.7.1 (2019-03-18)
修复由于会话验证而导致的测试失败。
0.7.0 (2019-03-18)
添加对 TOTP 的支持。
0.6.0 (2018-05-04)
在 OAuth 流中添加对 PKCE 质询和响应的支持。
添加在启动 OAuth 流时提供keys_jwk的功能。
基于新的 FxA 测试用例改进范围匹配逻辑,包括处理 URL 格式范围。
0.5.0 (2018-01-12)
添加使用解锁代码登录的功能。
告诉测试运行者忽略一些测试助手实用程序。
0.4.0 (2017-??-??)
使用pkg_resources处理软件包版本。(#45)
添加直接从 core.Session 授权 oauth 代码的快捷方式,而不是要求调用者显式创建断言。
0.3.0 (2016-09-07)
将verify_email_code(uid, code)方法添加到core.Client (#43)。
0.2.0 (2016-05-11)
确保可以在不安装 PyFxA 测试依赖项的情况下使用 fxa.tests.utils。(#41)
0.1.3 (2016-04-22)
更新 User-Agent 以便我们可以检测 PyFxA 调用。(#40)
0.1.2 (2016-04-21)
正确发送请求到 Auth 服务器。
0.1.1 (2016-01-13)
在生成 BrowserID 断言时正确配置证书持续时间 (#39)
0.1.0 (2016-01-07)
添加 fxa-client CLI 工具 (#36)
删除对 Python 2.6 的支持(#38)
0.0.9 (2015-08-15)
删除提及 PyFxA 仍处于高度实验性(#31)的说法
不要依赖要安装的软件包才能使用(#32)
0.0.8 (2015-08-14)
更新 setup.py 以处理 README 和 CHANGES 文件中的 utf-8 字符 (#29)
向 Auth 插件添加缓存功能 (#30)
0.0.7 (2015-07-23)
如果可用,请使用 grequests 以将 PyFxA 与 gevent 生态系统一起使用。
添加 oauth /destroy 操作。
个人资料提取会跳过您无权阅读的字段。
添加 BrowserID requests Auth 模块和相关的 HTTPie 插件。
添加 BearerToken requests Auth 模块和相关的 HTTPie 插件。
为使用 Python 2 处理安全 SSL 请求添加 PyOpenSSL 支持。
0.0.6 (2015-03-20)
在 oauth 缓存中公开 unicode,而不是字节串。
0.0.5 (2015-03-19)
指定请求依赖项的最低要求版本。
0.0.4 (2015-03-11)
- 添加用于检索个人资料信息的基本 API
使用 OAuth 令牌。
0.0.3 (2015-02-20)
重构 oauth.Client 以将 id/secret 作为构造函数参数。
在 oauth 令牌验证上添加基本缓存。
接受服务器 URL 上的选项“/v1”后缀。
将 get_identity_assertion() 方法添加到 core.Session。
向 oauth.Client 添加方法以授权代码和令牌。
为与信任相关的错误添加新的错误层次结构。
oauth 范围检查中的附加完整性检查。
0.0.2 (2015-01-05)
初始发行; 包括基本的身份验证和 oauth 功能。