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

Xamarin.Forms应用如何获取Firebase Auth的自定义Claims

Xamarin.Forms 跨端获取Firebase Auth自定义Claims方案

FirebaseAuthentication.net 库默认只映射了DisplayName、Email、PhoneNumber这类标准公开字段,自定义Claims实际存储在登录后下发的JWT格式ID Token的Payload中,不需要额外调用特殊接口,通过以下两种方案均可实现iOS、Android双端读取,完全兼容现有项目架构。


方案一:基于现有FirebaseAuthentication.net库直接解码(无需额外依赖)

这个方案不需要引入Firebase原生SDK,纯.NET Standard代码可直接放在共享项目中,双端通用。

  1. 获取有效ID Token
    自定义Claims更新后,强制刷新Token避免读取到缓存的旧版本,再取出原始Token字符串:
    // 复用你现有的登录逻辑获取当前用户
    var authConfig = new FirebaseConfig(你的Firebase Web API Key);
    var authProvider = new FirebaseAuthProvider(authConfig);
    var firebaseLoginResult = await authProvider.SignInWithEmailAndPasswordAsync(account, password);
    
    // 刚更新Claims时forceRefresh传true,常规场景传false减少请求
    await firebaseLoginResult.User.GetIdTokenAsync(forceRefresh: false);
    string rawJwtToken = firebaseLoginResult.User.FirebaseToken;
    
  2. 解码JWT Payload提取所有Claims
    JWT的Payload段为Base64Url编码,直接解码即可拿到包含自定义字段的完整键值对,生产环境如果需要做Token合法性校验,可额外引入JWT校验库验证签名,仅读取业务字段时无需额外校验(Firebase服务端会自动校验Token有效性):
    using System;
    using System.Text;
    using System.Text.Json;
    using System.Collections.Generic;
    
    private Dictionary<string, object> ParseFirebaseTokenClaims(string rawJwt)
    {
        // JWT结构为 [头部].[Payload].[签名],固定取第二段
        var payloadPart = rawJwt.Split('.')[1];
        // 处理Base64Url编码转标准Base64的补位
        payloadPart = payloadPart.Replace('-', '+').Replace('_', '/');
        payloadPart = (payloadPart.Length % 4) switch
        {
            2 => payloadPart + "==",
            3 => payloadPart + "=",
            _ => payloadPart
        };
        var payloadBytes = Convert.FromBase64String(payloadPart);
        var payloadJson = Encoding.UTF8.GetString(payloadBytes);
        return JsonSerializer.Deserialize<Dictionary<string, object>>(payloadJson);
    }
    
  3. 读取自定义Claims
    解码后直接按自定义字段的Key取值即可:
    var allClaims = ParseFirebaseTokenClaims(rawJwtToken);
    // 读取你存储的内部API凭证
    if (allClaims.TryGetValue("internal_api_credential", out var apiCred))
    {
        string internalApiCredential = apiCred.ToString();
    }
    // 读取其他自定义字段,注意和你在服务端设置的类型匹配
    if (allClaims.TryGetValue("user_permission_level", out var level))
    {
        int permissionLevel = int.Parse(level.ToString());
    }
    

方案二:基于Firebase原生SDK获取(适合已接入原生Firebase组件的项目)

如果你的项目已经引入了Xamarin.Firebase.Auth(Android)、Xamarin.Firebase.iOS.Auth(iOS)原生绑定包(通常接入Storage、Realtime Database时会用到),可以直接用原生SDK解析Claims,不需要自行处理JWT解码逻辑,稳定性更高。

  1. 在共享项目定义依赖服务接口:
    public interface IFirebaseAuthService
    {
        Task<Dictionary<string, object>> GetCurrentUserClaims(bool forceRefresh = false);
    }
    
  2. Android端实现:
    using Firebase.Auth;
    
    public class DroidFirebaseAuthService : IFirebaseAuthService
    {
        public async Task<Dictionary<string, object>> GetCurrentUserClaims(bool forceRefresh = false)
        {
            var currentUser = FirebaseAuth.Instance.CurrentUser;
            if (currentUser == null) throw new InvalidOperationException("用户未登录");
            var tokenResult = await currentUser.GetIdToken(forceRefresh);
            return tokenResult.Claims.ToDictionary(item => item.Key, item => item.Value);
        }
    }
    
  3. iOS端实现:
    using Firebase.Auth;
    
    public class IosFirebaseAuthService : IFirebaseAuthService
    {
        public Task<Dictionary<string, object>> GetCurrentUserClaims(bool forceRefresh = false)
        {
            var tcs = new TaskCompletionSource<Dictionary<string, object>>();
            var currentUser = Auth.DefaultInstance.CurrentUser;
            if (currentUser == null)
            {
                tcs.SetException(new InvalidOperationException("用户未登录"));
                return tcs.Task;
            }
            currentUser.GetIdToken(forceRefresh, (idToken, err) =>
            {
                if (err != null)
                {
                    tcs.SetException(new Exception(err.LocalizedDescription));
                    return;
                }
                var claims = idToken.Claims.ToDictionary(item => item.Key, item => item.Value);
                tcs.SetResult(claims);
            });
            return tcs.Task;
        }
    }
    
  4. 共享项目中通过依赖服务调用即可拿到所有Claims,取值逻辑和方案一一致。

注意事项

  • Firebase ID Token默认有效期为1小时,本地会自动缓存,非必要场景不要每次都强制刷新Token,避免产生多余网络请求
  • 自定义Claims总大小不能超过1000字节,这是Firebase的官方硬限制,超出会导致Token下发失败
  • 客户端获取的Claims仅可用于UI渲染、业务参数传递,所有接口权限校验必须在服务端完成,不可信任客户端传递的Claims值
  • 通过Admin SDK更新用户自定义Claims后,必须强制刷新客户端Token才能获取到最新值,否则会最长延迟1小时(等旧Token过期)才能生效

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 22:18:42