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

.NET 9 MAUI Android应用Google OAuth集成失败求助

MAUI Google OAuth 登录解决方案(替代自定义URI重定向)

问题背景

Google 已限制新创建的原生应用客户端(Android/iOS)使用自定义 URI 重定向,官方推荐使用 Google Sign-In SDK 或 Credential Manager API 完成登录流程,以下是两种可行的实现方案:


方案一:使用 Google Sign-In SDK(官方推荐,跨平台适配)

这是最稳定的实现方式,直接调用 Google 官方提供的原生登录组件,无需依赖自定义 URI。

步骤 1:安装依赖包

根据平台安装对应的 NuGet 包:

  • Android:Xamarin.GooglePlayServices.Auth
  • iOS:Xamarin.Google.iOS.SignIn
  • 跨平台基础包:Google.Apis.Auth.OAuth2

步骤 2:平台配置

Android(AndroidManifest.xml)

添加必要权限和组件:

<uses-permission android:name="android.permission.INTERNET" />
<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
<activity android:name="com.google.android.gms.auth.api.signin.internal.SignInHubActivity" android:excludeFromRecents="true" />

确保 Google 控制台中创建的 Android 客户端 ID 已正确配置包名和 SHA-1 指纹。

iOS(Info.plist)

添加 URL Scheme(格式为 com.googleusercontent.apps.{{你的客户端ID}}),并配置查询权限:

<key>CFBundleURLTypes</key>
<array>
  <dict>
    <key>CFBundleURLSchemes</key>
    <array>
      <string>com.googleusercontent.apps.1234567890-abcdefghijklmnopqrstuvwxyz</string>
    </array>
  </dict>
</array>
<key>LSApplicationQueriesSchemes</key>
<array>
  <string>googlechrome</string>
  <string>googlechromes</string>
</array>

确保 Google 控制台中创建的 iOS 客户端 ID 已正确配置 Bundle ID。

步骤 3:登录代码实现

创建跨平台的认证服务类:

using Google.Apis.Auth.OAuth2;
using Google.Apis.Auth.OAuth2.Flows;
using Google.Apis.Auth.OAuth2.Maui;

public class GoogleAuthService
{
    // 替换为你在Google控制台获取的对应平台客户端ID
    private const string AndroidClientId = "你的Android客户端ID";
    private const string IosClientId = "你的iOS客户端ID";

    public async Task<string> GetGoogleAccessTokenAsync()
    {
        var clientId = DeviceInfo.Platform == DevicePlatform.Android 
            ? AndroidClientId 
            : IosClientId;

        var authFlow = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
        {
            ClientSecrets = new ClientSecrets { ClientId = clientId },
            Scopes = new[] { "openid", "email", "profile" } // 根据需求添加权限
        });

        var authResult = await GoogleAuthenticator.AuthenticateAsync(authFlow, null, CancellationToken.None);

        if (authResult?.Credential != null && !string.IsNullOrEmpty(authResult.Credential.Token.AccessToken))
        {
            return authResult.Credential.Token.AccessToken;
        }

        throw new Exception("Google登录失败:未获取到有效AccessToken");
    }
}

方案二:使用 Credential Manager API(Google 新推荐方案)

Credential Manager 是 Google 推出的统一认证管理工具,适合需要集成多种登录方式的场景。

步骤 1:启用 API 并安装依赖

  • 在 Google 控制台启用 Credential Manager API
  • Android 安装 NuGet 包:Xamarin.GooglePlayServices.Credentials、Xamarin.GooglePlayServices.Auth.Credentials

步骤 2:Android 端代码实现

using Android.Gms.Auth.Credentials;
using Android.Gms.Auth.Api.Credentials;
using Android.App;

public class GoogleCredentialAuthService
{
    private readonly Activity _mainActivity;

    public GoogleCredentialAuthService(Activity mainActivity)
    {
        _mainActivity = mainActivity;
    }

    public async Task<string> AuthenticateWithCredentialManagerAsync()
    {
        var credentialClient = Credentials.GetClient(_mainActivity);
        var request = new CredentialRequest.Builder()
            .SetPasswordLoginSupported(false)
            .SetAccountTypes(IdentityProviders.Google)
            .Build();

        var result = await credentialClient.RequestAsync(request);

        if (result.Status.IsSuccess)
        {
            var credential = result.Credential;
            // 通过GoogleAuthUtil获取AccessToken
            var accessToken = await Android.Gms.Auth.GoogleAuthUtil.GetTokenAsync(
                _mainActivity,
                credential.AccountName,
                "oauth2:openid email profile");
            
            return accessToken;
        }
        else if (result.Status.StatusCode == CommonStatusCodes.ResolutionRequired)
        {
            // 启动Google登录界面
            await result.Status.StartResolutionForResultAsync(_mainActivity, 1001);
            // 需在MainActivity的OnActivityResult中处理返回结果
        }
        else
        {
            throw new Exception($"Credential Manager认证失败:{result.Status.StatusMessage}");
        }
    }
}

步骤 3:MainActivity 处理登录结果

protected override void OnActivityResult(int requestCode, Result resultCode, Android.Content.Intent data)
{
    base.OnActivityResult(requestCode, resultCode, data);
    if (requestCode == 1001 && resultCode == Result.Ok)
    {
        var credential = Credentials.GetClient(this).GetCredentialFromIntent(data);
        // 这里可以继续调用获取AccessToken的逻辑
    }
}

关键注意事项

  1. 客户端ID类型正确:必须在Google控制台创建Android/iOS原生应用客户端ID,而非Web应用客户端ID
  2. 平台配置匹配:包名、Bundle ID、SHA-1指纹必须与Google控制台配置完全一致
  3. 权限范围合理:只请求必要的OAuth权限(如openid、email、profile),避免过度授权

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 04:25:23