Xamarin中的离线身份验证最佳做法

Nes*_*tor 6 c# xamarin.ios xamarin

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

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

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

  • 在首选项中存储用户名和密码 - 它不加密,易于重置,易于获取等.
  • 在数据库中存储用户名和密码 - 它可以加密(我推测),易于重置

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

Ido*_*doT 12

这取决于您的应用程序需求 - 如果您只需要验证用户离线访问某些受限数据 - 我建议您散列用户名和密码,并将其存储在本地设备中(无论何处,它是散列的) .

如果您以后需要使用用户名和密码对服务器进行身份验证,那么您应该使用像keychain这样的安全数据,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);
}
Run Code Online (Sandbox Code Playgroud)

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>();
    }
}
Run Code Online (Sandbox Code Playgroud)

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>();
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

注意 - 我添加了两层数据,以便让第一层指示身份验证是否为Facebook/UserName-Password/other.第二层是数据本身 - 即facebook令牌/凭证.