我已经用纯粹的、独立的bash+curl+sed 写了一个illustrative proof-of-concept implementation。
它在很大程度上受到来自Team OpenXbox 的Xbox-Webapi 的xbox.webapi.authentication.manager module 的剽窃/压缩的启发,您可能应该改用它*。他们的 API 非常好,涵盖了这么多奥秘,以至于微软…simply fails to document;如果该库依赖于 Microsoft 的 Xbox Live API 来实现其核心功能,那么值得强烈考虑将您的项目切换到 Python。
简而言之,要使用此 API,看来您必须:
-
注册Application in Azure
- 如果您的应用程序可以绑定到将要授权应用程序的用户系统上的
localhost:8080,或者您有他们的合作(特别是:他们能够将code 参数粘贴到程序),您可以跳过此步骤,使用client_id=0000000048093EE3,并完全省略client_secret。 (在这种情况下,您甚至不需要 Azure 帐户。)
-
让any** Xbox Live 用户通过 OAuth2 向您的应用程序提供 Xboxlive.signin 和 Xboxlive.offline_access 范围
-
使用此授权和 Bearer 令牌从 https://user.auth.xboxlive.com/user/authenticate 获取所谓的“用户令牌”
-
使用该令牌向https://xsts.auth.xboxlive.com/xsts/authorize 进行身份验证,以获得“XToken”
-
使用该令牌向https://profile.xboxlive.com 验证您感兴趣的实际端点,例如/users/gt({gamertag})/profile/settings(其中包含XUID 等属性,作为十进制字符串 , 在属性"id")
(**显然,如果您要访问 特权 端点,例如查看私人信息或修改用户帐户设置的端点,您将对您需要谁的授权以及您的范围有额外的要求' 必须请求;但是,对于一般情况下的 gamertag-to-XUID 查找,任何用户只需登录即可。)
*为此,它会是这样的:
from asyncio import run as arun
from sys import argv
from os import path, environ
import subprocess
from aiohttp import ClientSession
from xbox.webapi.api.client import XboxLiveClient
from xbox.webapi.authentication.manager import AuthenticationManager
from xbox.webapi.authentication.models import OAuth2TokenResponse
async def gamertags_to_xuids(gamertags, client_id=environ["client_id"], client_secret=environ["client_secret"], token_jar=path.join(environ["HOME"], ".local", "share", "xbox", "tokens.json")):
assert len(gamertags) >= 1
global session
auth_mgr = AuthenticationManager(session, client_id, client_secret, "")
await freshen_tokens(auth_mgr, token_jar)
xbl_client = XboxLiveClient(auth_mgr)
ids = []
for gamertag in gamertags:
profile = await xbl_client.profile.get_profile_by_gamertag(gamertag)
ids.append(int(profile.profile_users[0].id))
xuids = [f"{id:016X}" for id in ids]
return xuids
async def freshen_tokens(auth_mgr, token_jar):
with open(token_jar, "r+") as f:
auth_mgr.oauth = OAuth2TokenResponse.parse_raw(f.read())
await auth_mgr.refresh_tokens()
f.seek(0)
f.truncate()
f.write(auth_mgr.oauth.json())
async def amain(args):
global session
subprocess.run(["xbox-authenticate"], check=True)#TODO: avoid this system call
async with ClientSession() as session:
return await gamertags_to_xuids(args)
def main(args=argv[1:]):
return arun(amain(args))
if __name__ == '__main__':
for xuid in main():
print(xuid)