Xamarin 中的脱机身份验证最佳做法

本文关键字:最佳 身份验证 脱机 Xamarin | 更新日期: 2023-09-27 17:55:21

我打算创建一个Xamarin(.表单)应用程序,并且它必须具有身份验证:用户应提供用户名和密码以获取数据。

问题是它也必须离线工作(这意味着它不应该依赖服务器进行身份验证过程)。

到目前为止,我考虑了以下内容:

  • 将用户名和密码存储在首选项中 - 它未加密,易于重置,易于获取等。
  • 将用户名和密码存储在数据库中 - 它可以加密(我认为),易于重置

最佳实践是什么?是否有适用于 Xamarin 的内置解决方案?

Xamarin 中的脱机身份验证最佳做法

这取决于您的应用程序需求 - 如果您只需要对用户进行身份验证以离线访问一些受限数据 - 我建议您对用户名和密码进行哈希处理,并将其存储在本地设备中(无论在哪里,它都是哈希处理的)。

如果你以后需要使用用户名和密码向服务器进行身份验证,那么你应该使用像钥匙串这样的安全数据,Xamarin有一个内置的抽象来使用它,它被称为Xamarin.Auth,你可以在其中安全地存储你的凭据。

*注意 - 在越狱/root设备中存储敏感数据是有风险的,请谨慎使用。

编辑 - 我添加了如何使用和使用这些服务的工作代码示例:

1) 在您的便携式项目中添加此接口:

public interface ISecuredDataProvider
{
    void Store(string userId, string providerName, IDictionary<string, string> data);
    void Clear(string providerName);
    Dictionary<string, string> Retreive(string providerName);
}

2) 在您的 Android 项目中,添加以下实现:

public class AndroidSecuredDataProvider : ISecuredDataProvider
{
    public void Store(string userId, string providerName, IDictionary<string, string> data)
    {
        Clear(providerName);
        var accountStore = AccountStore.Create(Android.App.Application.Context);
        var account = new Account(userId, data);
        accountStore.Save(account, providerName);
    }
    public void Clear(string providerName)
    {
        var accountStore = AccountStore.Create(Android.App.Application.Context);
        var accounts = accountStore.FindAccountsForService(providerName);
        foreach (var account in accounts)
        {
            accountStore.Delete(account, providerName);
        }
    }
    public Dictionary<string, string> Retreive(string providerName)
    {
        var accountStore = AccountStore.Create(Android.App.Application.Context);
        var accounts =  accountStore.FindAccountsForService(providerName).FirstOrDefault();
        return (accounts != null) ? accounts.Properties : new Dictionary<string, string>();
    }
}

3) 在 iOS 项目中,添加此实现:

  public class IOSSecuredDataProvider : ISecuredDataProvider
{
    public void Store(string userId, string providerName, IDictionary<string, string> data)
    {
        Clear(providerName);
        var accountStore = AccountStore.Create();
        var account = new Account(userId, data);
        accountStore.Save(account, providerName);
    }
    public void Clear(string providerName)
    {
        var accountStore = AccountStore.Create();
        var accounts = accountStore.FindAccountsForService(providerName);
        foreach (var account in accounts)
        {
            accountStore.Delete(account, providerName);
        }   
    }
    public Dictionary<string, string> Retreive(string providerName)
    {
        var accountStore = AccountStore.Create();
        var accounts = accountStore.FindAccountsForService(providerName).FirstOrDefault();
        return (accounts != null) ? accounts.Properties : new Dictionary<string, string>();
    }
}

4)用法示例 - 获取Facebook令牌后,我们将像这样存储它:

securedDataProvider.Store(user.Id, "FacebookAuth", new Dictionary<string, string> { { "FacebookToken", token } });

注意 - 我添加了两层数据,以便第一层指示身份验证是否是Facebook/用户名密码/其他。第二层是数据本身 - 即Facebook令牌/凭据。