升级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
相关产品推荐
相关产品推荐

