BackendAuthClient

Struct BackendAuthClient 

Source
pub struct BackendAuthClient { /* private fields */ }
Expand description

后端授权客户端 - 完全无状态设计

专为后端API开发者设计的微信授权客户端,处理“前端传code,后端验证“的场景。

§特点

  • 完全无状态:不缓存token、不管理refresh_token、不管理会话
  • 极简接口:仅封装微信API调用,没有复杂的Manager层
  • 后端全权管理:token存储、会话管理完全由业务代码决定
  • 通用性:支持公众号、开放平台、移动应用的code验证

§示例

use wechat_backend_auth::*;

let client = BackendAuthClient::new(
    BackendConfig::builder()
        .app_id(AppId::new("wx1234567890abcdef"))
        .app_secret(AppSecret::new("your_app_secret_here"))
        .build()
)?;

// 换取token
let token_resp = client
    .exchange_code(AuthorizationCode::new("code_from_frontend"))
    .await?;

// 获取用户信息
let user_info = client
    .get_user_info(&token_resp.access_token, &token_resp.openid)
    .await?;

println!("用户登录: {} ({})", user_info.nickname, user_info.openid);

Implementations§

Source§

impl BackendAuthClient

Source

pub fn new(config: BackendConfig) -> Result<Self, WeChatError>

创建新的后端授权客户端

§参数
  • config: 后端授权配置
§返回

返回配置好的客户端实例或配置错误

§示例
use wechat_backend_auth::*;

let client = BackendAuthClient::new(
    BackendConfig::builder()
        .app_id(AppId::new("wxAppId"))
        .app_secret(AppSecret::new("secret"))
        .build()
)?;
Source

pub async fn exchange_code( &self, code: AuthorizationCode, ) -> Result<TokenResponse, WeChatError>

使用授权码换取访问令牌

调用微信 oauth2/access_token 接口,使用前端传来的code换取:

  • access_token: 访问令牌(有效期2小时)
  • refresh_token: 刷新令牌(有效期30天)
  • openid: 用户唯一标识
  • unionid: 开放平台统一标识(可选)
§参数
  • code: 前端通过微信授权获取的临时授权码(有效期5分钟,只能使用一次)
§返回

返回 TokenResponse,包含token和用户标识,不会自动存储

§后续处理

后端开发者需要自行决定token的处理方式:

  • 存入数据库/Redis(如需长期使用)
  • 直接返回给前端(让前端管理)
  • 立即调用 get_user_info() 后丢弃
§示例
let token_resp = client
    .exchange_code(AuthorizationCode::new(code))
    .await?;

// 后端决定token的去向
// redis.set(
//     format!("wechat:token:{}", token_resp.openid),
//     &token_resp,
//     token_resp.expires_in
// ).await?;
Source

pub async fn get_user_info( &self, access_token: &AccessToken, openid: &OpenId, ) -> Result<UserInfo, WeChatError>

获取用户详细信息

使用 access_token 调用微信 sns/userinfo 接口获取用户资料。

§参数
  • access_token: 访问令牌(来自 exchange_code() 或存储的历史token)
  • openid: 用户唯一标识
§返回

返回 UserInfo,包含:

  • openid: 用户标识
  • nickname: 昵称
  • headimgurl: 头像URL
  • sex: 性别
  • province/city/country: 地域信息
  • unionid: 开放平台统一标识(可选)
§注意
  • 需要用户授权了 snsapi_userinfo 作用域
  • 如果只授权了 snsapi_base,只能获取 openid
  • token可能已过期,需要处理 AccessTokenExpired 错误
§示例
let user_info = client
    .get_user_info(&token_resp.access_token, &token_resp.openid)
    .await?;

println!("用户昵称: {}", user_info.nickname);
Source

pub async fn validate_token( &self, access_token: &AccessToken, openid: &OpenId, ) -> Result<bool, WeChatError>

验证访问令牌是否有效

调用微信 sns/auth 接口检查 access_token 是否仍然有效。

§参数
  • access_token: 要验证的访问令牌
  • openid: 用户唯一标识
§返回
  • Ok(true): token有效
  • Ok(false): token无效或已过期
§使用场景
  • 前端传来token,验证其有效性
  • 使用缓存的历史token前先验证
  • 决定是否需要调用 refresh_token()
§示例
if !client.validate_token(cached_token, openid).await? {
    // token已过期,需要刷新或重新授权
    // let new_token = client.refresh_token(&refresh_token).await?;
}
Source

pub async fn refresh_token( &self, refresh_token: &RefreshToken, ) -> Result<TokenResponse, WeChatError>

刷新访问令牌

使用 refresh_token 获取新的 access_tokenrefresh_token 有效期为30天,比 access_token(2小时)长得多。

§参数
  • refresh_token: 刷新令牌(从 exchange_code() 响应中获取)
§返回

返回新的 TokenResponse,不会自动存储,需手动更新缓存

§注意
  • refresh_token 本身也会更新,需要同时保存新的 refresh_token
  • 如果 refresh_token 也过期,需要重新引导用户授权
§示例
// 刷新获取新token
let new_token = client
    .refresh_token(old_refresh_token)
    .await?;

// 更新数据库
// db.update_token(&openid, &new_token).await?;

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more