You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET MAUI中WebAuthenticator使用refresh_token刷新access_token实现咨询

.NET MAUI WebAuthenticator 过期令牌后端刷新实现

核心逻辑

客户端检测到access_token过期后,将认证提供商标识(如google/microsoft/apple)和refresh_token发送到后端接口,后端根据对应厂商的OAuth2规范发起刷新请求,获取新的access_token(可能附带新的refresh_token)后返回给客户端。


各厂商具体实现代码(C# 后端示例)

以下示例基于HttpClient实现,需确保后端已配置对应厂商的ClientId和ClientSecret(苹果需额外生成JWT格式的ClientSecret)。

1. 谷歌 OAuth2 令牌刷新

public async Task<TokenRefreshResponse> RefreshGoogleToken(string refreshToken)
{
    var client = new HttpClient();
    var requestContent = new FormUrlEncodedContent(new Dictionary<string, string>
    {
        ["client_id"] = "你的谷歌ClientId",
        ["client_secret"] = "你的谷歌ClientSecret",
        ["refresh_token"] = refreshToken,
        ["grant_type"] = "refresh_token"
    });

    var response = await client.PostAsync("https://oauth2.googleapis.com/token", requestContent);
    response.EnsureSuccessStatusCode();
    
    var responseContent = await response.Content.ReadFromJsonAsync<TokenRefreshResponse>();
    return responseContent;
}

// 通用响应模型
public class TokenRefreshResponse
{
    public string access_token { get; set; }
    public int expires_in { get; set; }
    public string refresh_token { get; set; } // 谷歌可能返回新的refresh_token,需更新存储
    public string token_type { get; set; }
}

2. 微软 OAuth2 令牌刷新

public async Task<TokenRefreshResponse> RefreshMicrosoftToken(string refreshToken)
{
    var client = new HttpClient();
    var requestContent = new FormUrlEncodedContent(new Dictionary<string, string>
    {
        ["client_id"] = "你的微软ClientId",
        ["client_secret"] = "你的微软ClientSecret",
        ["refresh_token"] = refreshToken,
        ["grant_type"] = "refresh_token",
        ["scope"] = "openid email profile" // 需与初始授权的scope一致
    });

    var response = await client.PostAsync("https://login.microsoftonline.com/common/oauth2/v2.0/token", requestContent);
    response.EnsureSuccessStatusCode();
    
    var responseContent = await response.Content.ReadFromJsonAsync<TokenRefreshResponse>();
    return responseContent;
}

3. 苹果 Sign in with Apple 令牌刷新

苹果的刷新请求需要使用JWT格式的client_secret,需先生成该JWT:

// 生成苹果ClientSecret的工具方法
private string GenerateAppleClientSecret()
{
    var privateKey = "你的苹果私钥内容";
    var keyId = "你的苹果KeyId";
    var teamId = "你的苹果TeamId";
    var clientId = "你的苹果ClientId";

    var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(privateKey));
    var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);

    var token = new JwtSecurityToken(
        issuer: teamId,
        audience: "https://appleid.apple.com",
        claims: new[] { new Claim("sub", clientId) },
        expires: DateTime.UtcNow.AddMinutes(5),
        signingCredentials: credentials);

    return new JwtSecurityTokenHandler().WriteToken(token);
}

// 刷新令牌方法
public async Task<TokenRefreshResponse> RefreshAppleToken(string refreshToken)
{
    var client = new HttpClient();
    var clientSecret = GenerateAppleClientSecret();
    
    var requestContent = new FormUrlEncodedContent(new Dictionary<string, string>
    {
        ["client_id"] = "你的苹果ClientId",
        ["client_secret"] = clientSecret,
        ["refresh_token"] = refreshToken,
        ["grant_type"] = "refresh_token"
    });

    var response = await client.PostAsync("https://appleid.apple.com/auth/token", requestContent);
    response.EnsureSuccessStatusCode();
    
    var responseContent = await response.Content.ReadFromJsonAsync<TokenRefreshResponse>();
    return responseContent;
}

关键注意事项

  • 存储更新:部分厂商(如谷歌)会返回新的refresh_token,后端需将其返回给客户端,客户端替换本地旧的refresh_token。
  • 错误处理:若refresh_token过期或无效,后端需返回明确错误,客户端引导用户重新发起认证流程。
  • 安全规范:后端需妥善保管ClientSecret和苹果私钥,避免硬编码,建议使用配置中心或环境变量存储。
  • Scope一致性:微软刷新请求的scope需与初始授权时的scope保持一致,否则可能导致请求失败。

内容的提问来源于stack exchange,提问作者Jean

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 13:51:18