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

.NET MAUI项目集成Google与Apple登录遇阻,求技术指导

.NET MAUI 集成Google/Apple登录解决方案

一、Google登录实现(替代Xamarin.Auth与内置WebView)

放弃Xamarin.Auth和自定义WebView,使用.NET MAUI官方提供的WebAuthenticator——它基于系统原生浏览器处理认证,能避免重定向回调问题:

1. 控制台配置确认

  • 在Google Cloud Console中,为各平台配置正确参数:
    • Android:填写包名、SHA-1指纹;重定向URI格式为com.googleusercontent.apps.{你的客户端ID后缀}:/oauth2redirect
    • iOS/macOS:填写Bundle ID;重定向URI使用{你的Bundle ID}:/oauth2redirect
  • 启用「Google People API」或「Userinfo API」(用于后续获取用户信息)

2. 代码实现

using Microsoft.Maui.Authentication;

public async Task<string> GoogleLoginAsync()
{
    var authUrl = new Uri("https://accounts.google.com/o/oauth2/v2/auth" +
        "?client_id={你的Google客户端ID}" +
        "&redirect_uri={你的重定向URI}" +
        "&response_type=code" +
        "&scope=openid email profile");

    var result = await WebAuthenticator.AuthenticateAsync(authUrl, new Uri("{你的重定向URI}"));

    // 获取授权码,可进一步交换为AccessToken和RefreshToken(调用Google Token API)
    var code = result.Properties["code"];
    return code;
}

二、Apple登录实现

1. iOS/macOS原生登录

使用Apple原生授权控件,体验更贴合系统:

#if IOS || MACCATALYST
using AuthenticationServices;

public void SetupAppleLoginButton()
{
    var appleButton = new ASAuthorizationAppleIDButton();
    appleButton.TouchUpInside += async (s, e) =>
    {
        var provider = new ASAuthorizationAppleIDProvider();
        var request = provider.CreateRequest();
        request.RequestedScopes = new[] { ASAuthorizationScope.Email, ASAuthorizationScope.FullName };

        var controller = new ASAuthorizationController(new[] { request });
        controller.Delegate = this;
        controller.PresentationContextProvider = this;
        controller.PerformRequests();
    };
    // 将button添加到页面布局
}

// 实现ASAuthorizationControllerDelegate接口
[Export("authorizationController:didCompleteWithAuthorization:")]
public void DidComplete(ASAuthorizationController controller, ASAuthorization authorization)
{
    if (authorization is ASAuthorizationAppleIDCredential appleCredential)
    {
        var userID = appleCredential.User;
        var email = appleCredential.Email;
        var fullName = appleCredential.FullName;
        var identityToken = appleCredential.IdentityToken;
        var accessToken = appleCredential.AuthorizationCode;
        // 处理凭证信息
    }
}
#endif

2. Android/Web平台登录

同样使用WebAuthenticator,重定向URI格式为{你的Android包名}:/callback,需在Apple Developer Console中配置对应的服务ID和重定向URI:

public async Task<string> AppleLoginAsync()
{
    var authUrl = new Uri("https://appleid.apple.com/auth/authorize" +
        "?client_id={你的Apple服务ID}" +
        "&redirect_uri={你的重定向URI}" +
        "&response_type=code id_token" +
        "&scope=name email" +
        "&response_mode=query");

    var result = await WebAuthenticator.AuthenticateAsync(authUrl, new Uri("{你的重定向URI}"));
    var idToken = result.Properties["id_token"];
    var code = result.Properties["code"];
    return idToken;
}

三、获取用户邮箱、姓名等信息

1. Google平台

拿到AccessToken后,调用Google Userinfo API:

using System.Net.Http;
using System.Text.Json;

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

public class GoogleUserInfo
{
    public string Name { get; set; }
    public string Email { get; set; }
    public string Picture { get; set; }
}

2. Apple平台

  • iOS/macOS:在DidComplete回调中直接从ASAuthorizationAppleIDCredential获取Email和FullName
  • Android/Web:解析id_token(JWT格式)提取用户信息,或调用Apple令牌验证接口获取详情

四、安全存储认证令牌

使用.NET MAUI内置的SecureStorage,它基于各平台原生安全机制存储(Android用Keystore,iOS用Keychain):

using Microsoft.Maui.Storage;

// 存储令牌
public async Task SaveTokenAsync(string tokenKey, string tokenValue)
{
    await SecureStorage.SetAsync(tokenKey, tokenValue);
}

// 获取令牌
public async Task<string> GetTokenAsync(string tokenKey)
{
    return await SecureStorage.GetAsync(tokenKey);
}

// 删除令牌
public async Task RemoveTokenAsync(string tokenKey)
{
    SecureStorage.Remove(tokenKey);
}

注意事项

  • Android平台:确保目标SDK版本≥23,SecureStorage会自动处理权限
  • iOS平台:无需额外配置,直接使用即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 09:37:40