3个版本

0.1.2 2023年12月21日
0.1.1 2023年12月20日
0.1.0 2022年11月12日

#552 in 身份验证

MIT 许可证

160KB
2.5K SLoC

xal - Xbox身份验证库 for Rust

Crates.io Docs.rs CI

使用Xbox Live进行身份验证

文档

在此处查找文档:https://docs.rs/xal

示例

查看 xal-examples

最低支持的Rust版本

此crate需要至少Rust 1.70 (稳定版)。

免责声明

这是一个未经微软认可的库,不承担任何责任。使用风险自担!


lib.rs:

XAL - Xbox Live身份验证库 for Rust

此库旨在为用户提供高可配置性,以便可以对每个所需的场景进行针对性的身份验证。

功能

快速开始

验证并保存令牌到JSON文件 tokens.json

use xal::{XalAuthenticator, Flows, CliCallbackHandler};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut authenticator = XalAuthenticator::default();

    // Do full SISU auth flow
    let mut token_store = Flows::xbox_live_sisu_full_flow(
        &mut authenticator,
        CliCallbackHandler
    ).await?;

    // User will be prompted on commandline to proceed with authentication

    token_store.update_timestamp();
    token_store.save_to_file("tokens.json")?;
    
    Ok(())
}

从文件加载令牌并刷新它们

use xal::{XalAuthenticator, Flows, CliCallbackHandler};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    println!("Trying to refresh tokens...");
    let mut token_store = match Flows::try_refresh_live_tokens_from_file("tokens.json").await {
        Ok((mut authenticator, ts)) => {
            println!("Tokens refreshed succesfully, proceeding with Xbox Live Authorization");
            Flows::xbox_live_sisu_authorization_flow(&mut authenticator, ts.live_token)
                .await?
        },
        Err(err) => {
            eprintln!("Refreshing tokens failed err={err}");
            let mut authenticator = XalAuthenticator::default();
            println!("Authentication via SISU");
            Flows::xbox_live_sisu_full_flow(&mut authenticator, CliCallbackHandler)
                .await?
        }
    };

    token_store.update_timestamp();
    token_store.save_to_file("tokens.json")?;
    Ok(())
}

使用获取到的XSTS令牌

use xal::{XalAuthenticator, Flows, CliCallbackHandler};
use xal::extensions::JsonExDeserializeMiddleware;
use xal::oauth2::TokenResponse;
use serde_json::json;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create an authenticator with minecraft client parameters
    let mut authenticator = XalAuthenticator::new(
        xal::app_params::MC_BEDROCK_SWITCH(),
        xal::client_params::CLIENT_NINTENDO(),
        "RETAIL".into(),
    );

    // Do full SISU authentication flow
    let mut token_store = Flows::xbox_live_sisu_full_flow(
        &mut authenticator,
        CliCallbackHandler
    ).await?;

    // Authorize to XSTS endpoint via Minecraft RelyingParty
    let xsts_mc_services = authenticator
        .get_xsts_token(
            token_store.device_token.as_ref(),
            token_store.title_token.as_ref(),
            token_store.user_token.as_ref(),
            "rp://api.minecraftservices.com/"
        )
        .await?;

    let identity_token = xsts_mc_services.authorization_header_value();
    println!("identityToken: {identity_token}");
    
    /* Minecraft stuff */
    // Exchange XSTS Token against Minecraft Token
    let mc_token = reqwest::Client::new()
        .post("https://api.minecraftservices.com/authentication/login_with_xbox")
        .json(&json!({"identityToken": identity_token}))
        .send()
        .await?
        .json_ex::<xal::oauth2::basic::BasicTokenResponse>()
        .await?;
    println!("MC: {mc_token:?}");
    
    // Get minecraft profile, use Minecraft Token as Bearer Auth
    let profile = reqwest::Client::new()
        .get("https://api.minecraftservices.com/minecraft/profile")
        .bearer_auth(mc_token.access_token().secret())
        .send()
        .await?
        .text()
        .await?;
    println!("Profile: {profile}");
    Ok(())
}

从文件加载令牌并发送一个已签名的请求

use xal::{
    RequestSigner, TokenStore, Error,
    extensions::{
        SigningReqwestBuilder,
        CorrelationVectorReqwestBuilder,
        
    },
    cvlib::CorrelationVector,
};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Load tokens from JSON
    let token_store = TokenStore::load_from_file("tokens.json")?;

    // Create new instances of Correlation vector and request signer
    let mut cv = CorrelationVector::new();
    let mut signer = RequestSigner::new();

    // Check if XSTS token exists
    let xsts_token = token_store.authorization_token
        .ok_or(Error::GeneralError("No XSTS token was acquired".into()))?;

    // Send a http request
    // Request will get signed and MS-CV header populated
    let userpresence = reqwest::Client::new()
        .get("https://userpresence.xboxlive.com/users/me?level=all")
        .header("x-xbl-contract-version", "3")
        .header("Authorization", xsts_token.authorization_header_value())
        .add_cv(&mut cv)?
        .sign(&mut signer, None)
        .await?
        .send()
        .await?;
   
    println!("{:?}", userpresence);   
    Ok(())
}

示例

查看xal-examples

高级

有关高级用法,请参阅 crate::XalAuthenticator.

依赖关系

~9–25MB
~360K SLoC