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

升级Google.Apis.Oauth2.v2至v1.60后UWP应用Google登录遇权限及线程问题

解决UWP应用Google登录的问题

问题根源

GoogleWebAuthorizationBroker是为桌面应用设计的组件,在UWP的沙箱环境中存在兼容性问题——即使指定了FileDataStore路径,它内部的浏览器交互逻辑仍依赖桌面环境特性,导致线程终止和错误弹窗。

替代方案:使用UWP原生WebAuthenticationBroker实现Google OAuth2登录

绕开GoogleWebAuthorizationBroker,用UWP自带的WebAuthenticationBroker完成授权流程,步骤如下:

1. 准备Google OAuth2配置

在Google Cloud控制台正确配置UWP应用的OAuth2客户端:

  • 客户端类型选择「桌面应用」(UWP在OAuth2体系中归类为桌面应用)
  • 记录客户端ID和客户端密钥

2. 实现完整授权流程

using System.Net.Http;
using System.Threading.Tasks;
using Windows.Security.Authentication.Web;
using Windows.Data.Json;
using System.Collections.Generic;

public async Task<string> GetGoogleAccessToken()
{
    // 替换为你的Google客户端信息
    string clientId = "你的Google客户端ID";
    string clientSecret = "你的Google客户端密钥";
    
    // 获取UWP应用的回调URI
    string redirectUri = WebAuthenticationBroker.GetCurrentApplicationCallbackUri().ToString();
    string scope = "profile email";

    // 构造授权请求URL
    string authUrl = $"https://accounts.google.com/o/oauth2/v2/auth?client_id={clientId}&redirect_uri={Uri.EscapeDataString(redirectUri)}&response_type=code&scope={Uri.EscapeDataString(scope)}&access_type=offline&prompt=consent";

    // 启动授权界面
    WebAuthenticationResult result = await WebAuthenticationBroker.AuthenticateAsync(
        WebAuthenticationOptions.None,
        new Uri(authUrl),
        new Uri(redirectUri));

    if (result.ResponseStatus != WebAuthenticationStatus.Success)
    {
        return null; // 授权失败,自行处理错误逻辑
    }

    // 从响应中提取授权码
    string responseData = result.ResponseData;
    string authCode = responseData.Substring(responseData.IndexOf("code=") + 5).Split('&')[0];

    // 用授权码换取Access Token和Refresh Token
    using (HttpClient client = new HttpClient())
    {
        var formData = new FormUrlEncodedContent(new[]
        {
            new KeyValuePair<string, string>("code", authCode),
            new KeyValuePair<string, string>("client_id", clientId),
            new KeyValuePair<string, string>("client_secret", clientSecret),
            new KeyValuePair<string, string>("redirect_uri", redirectUri),
            new KeyValuePair<string, string>("grant_type", "authorization_code")
        });

        HttpResponseMessage tokenResponse = await client.PostAsync("https://oauth2.googleapis.com/token", formData);
        string tokenJson = await tokenResponse.Content.ReadAsStringAsync();
        JsonObject tokenObj = JsonObject.Parse(tokenJson);

        // 提取Access Token,用于后续调用Google API
        string accessToken = tokenObj.GetNamedString("access_token");
        // 保存Refresh Token,用于后续刷新Access Token
        string refreshToken = tokenObj.GetNamedString("refresh_token");
        
        // 可将refreshToken存储到UWP本地存储,比如ApplicationData.Current.LocalSettings
        ApplicationData.Current.LocalSettings.Values["GoogleRefreshToken"] = refreshToken;

        return accessToken;
    }
}

3. 使用Access Token调用Google API

拿到Access Token后,即可调用用户信息等API:

public async Task<string> GetGoogleUserInfo(string accessToken)
{
    using (HttpClient client = new HttpClient())
    {
        client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken);
        HttpResponseMessage response = await client.GetAsync("https://www.googleapis.com/oauth2/v2/userinfo");
        return await response.Content.ReadAsStringAsync();
    }
}

4. 处理Token刷新

当Access Token过期时,用保存的Refresh Token刷新:

public async Task<string> RefreshGoogleAccessToken()
{
    string clientId = "你的Google客户端ID";
    string clientSecret = "你的Google客户端密钥";
    string refreshToken = ApplicationData.Current.LocalSettings.Values["GoogleRefreshToken"] as string;

    if (string.IsNullOrEmpty(refreshToken))
    {
        return null;
    }

    using (HttpClient client = new HttpClient())
    {
        var formData = new FormUrlEncodedContent(new[]
        {
            new KeyValuePair<string, string>("refresh_token", refreshToken),
            new KeyValuePair<string, string>("client_id", clientId),
            new KeyValuePair<string, string>("client_secret", clientSecret),
            new KeyValuePair<string, string>("grant_type", "refresh_token")
        });

        HttpResponseMessage tokenResponse = await client.PostAsync("https://oauth2.googleapis.com/token", formData);
        string tokenJson = await tokenResponse.Content.ReadAsStringAsync();
        JsonObject tokenObj = JsonObject.Parse(tokenJson);
        
        return tokenObj.GetNamedString("access_token");
    }
}

关键注意事项

  • 必须将WebAuthenticationBroker.GetCurrentApplicationCallbackUri()返回的URL(格式类似ms-app://s-1-15-2-xxxxxxxxx-xxxxxxxxx-xxxxxxxxx-xxxxxxxxx-xxxxxxxxx-xxxxxxxxx-xxxxxxxxx/)添加到Google Cloud控制台的「已授权的重定向URI」列表中
  • 所有敏感数据(如Refresh Token)需存储在UWP沙箱允许的位置,比如ApplicationData.Current.LocalSettings或LocalCacheFolder

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 01:22:44