自定义身份提供程序
实现自定义终端用户身份提供程序,将 Convai 的记忆和 MAU 跟踪绑定到你自己的认证系统、学习者记录或自助终端登录流程。
最后更新于
这有帮助吗?
这有帮助吗?
public interface IEndUserMetadataProvider
{
IReadOnlyDictionary<string, object> GetEndUserMetadata();
}// AuthIdentityProvider.cs
using System.Collections.Generic;
using Convai.Domain.Identity;
public class AuthIdentityProvider : IEndUserIdentityProvider, IEndUserMetadataProvider
{
private readonly IAuthService _authService;
public AuthIdentityProvider(IAuthService authService)
{
_authService = authService;
}
// 每次 ConnectAsync() 只调用一次——必须返回一个稳定的非空字符串。
public string GetEndUserId()
{
string userId = _authService.CurrentUserId;
if (string.IsNullOrEmpty(userId))
throw new System.InvalidOperationException(
"用户未认证。请确保登录在连接到 Convai 之前完成。");
return userId;
}
// 每次 ConnectAsync() 只调用一次——如果不需要元数据,则返回空字典。
public IReadOnlyDictionary<string, object> GetEndUserMetadata()
{
return new Dictionary<string, object>
{
["displayName"] = _authService.CurrentUserDisplayName ?? "Unknown",
["role"] = _authService.CurrentUserRole ?? "learner",
["department"] = _authService.CurrentUserDepartment ?? string.Empty
};
}
}// AuthSceneInitializer.cs
using Convai.Runtime.Components;
using UnityEngine;
public class AuthSceneInitializer : MonoBehaviour
{
[SerializeField] private AuthService _authService;
private async void Start()
{
// 确保用户在 Convai 连接之前已登录。
await _authService.EnsureLoggedInAsync();
ConvaiManager manager = ConvaiManager.ActiveManager;
if (manager == null)
{
Debug.LogError("[AuthSceneInitializer] 场景中未找到 ConvaiManager。");
return;
}
var provider = new AuthIdentityProvider(_authService);
manager.SetEndUserIdentityProvider(provider);
manager.SetEndUserMetadataProvider(provider);
// 现在可以安全连接——身份已解析。
await manager.ConnectAsync();
}
}// AuthConvaiManager.cs
using Convai.Runtime.Components;
using Convai.Runtime.Core;
public class AuthConvaiManager : ConvaiManager
{
private AuthService _authService;
protected override ConvaiRuntimeBuilder CreateRuntimeBuilder()
{
ConvaiRuntimeBuilder builder = base.CreateRuntimeBuilder();
// _authService 必须在 Awake() 之前解析——在这里注入或查找它。
_authService = FindObjectOfType<AuthService>();
if (_authService != null)
{
var provider = new AuthIdentityProvider(_authService);
builder.WithEndUserIdentityProvider(provider);
builder.WithEndUserMetadataProvider(provider);
}
return builder;
}
}public class LmsIdentityProvider : IEndUserIdentityProvider, IEndUserMetadataProvider
{
private readonly LmsSession _session;
public LmsIdentityProvider(LmsSession session) => _session = session;
public string GetEndUserId() => _session.LearnerId; // 例如,"emp-12345"
public IReadOnlyDictionary<string, object> GetEndUserMetadata()
{
return new Dictionary<string, object>
{
["name"] = _session.LearnerName,
["courseId"] = _session.CourseId,
["cohort"] = _session.CohortCode
};
}
}public class KioskIdentityProvider : IEndUserIdentityProvider
{
public static KioskIdentityProvider Instance { get; } = new();
// 每次连接前由自助终端登录 UI 更新。
public string ActiveResidentId { get; set; }
public string GetEndUserId()
{
if (string.IsNullOrEmpty(ActiveResidentId))
throw new System.InvalidOperationException("没有住院医师登录。");
return $"resident-{ActiveResidentId}";
}
}public class BackendAuthIdentityProvider : IEndUserIdentityProvider
{
private readonly string _stableUserId;
// stableUserId 从你的后端认证令牌中获取(例如 JWT 的 sub claim)。
public BackendAuthIdentityProvider(string stableUserId)
{
if (string.IsNullOrEmpty(stableUserId))
throw new System.ArgumentException("用户 ID 不能为空或空字符串。", nameof(stableUserId));
_stableUserId = stableUserId;
}
public string GetEndUserId() => _stableUserId;
}