【问题标题】:SecureStorage does not throw an exception when key does not exist当密钥不存在时,SecureStorage 不会抛出异常
【发布时间】:2021-10-11 11:28:42
【问题描述】:

我的应用程序中发生了一个非常奇怪的错误。

我有一个非常简单的辅助方法,用于在用户设备上存储一些很酷的数据:

public static async Task TrySetAsync(string key, string value)
    {
        try
        {
            await SecureStorage.SetAsync(key, value);
        }
        catch (Exception ex)
        {
            await App.Current.MainPage.DisplayAlert(
                "Device incompatible",
                "Your device is not compatible with this app.",
                "Ok");
        }
    }

它工作得很好,从来没有出现过问题,但我决定在应用启动时执行兼容性检查,以便用户立即知道他们的设备不会切断它。为此,我决定在初始登录页面的 OnAppearing() 方法中实现它。它看起来像这样:

protected override async void OnAppearing()
    {
        try
        {
            // Try to save data to a random container
            string tempKey = System.Guid.NewGuid().ToString();

            //  Should throw an exception if SecureStorage is not compatible
            await Xamarin.Essentials.SecureStorage
                .SetAsync(tempKey, string.Empty);

            // Remove the datum
            Xamarin.Essentials.SecureStorage
                .Remove(tempKey);
        }
        catch
        {
            await App.Current.MainPage.DisplayAlert(
                "Device incompatible", 
                "This device does not support secure storage required for the application.", 
                "Ok");

            App.Terminate();
        }


        base.OnAppearing();
    }

我从项目中删除了权利来测试我的小混合物,但它毫无问题地通过了它。不会抛出异常。但是在登录时,使用原始 TrySetAsync 方法(第一个代码 sn-p)时,会引发预期的异常(缺少权利)。调试器进入 try 块并没有问题地离开它。

总结:

看起来,当在 OnAppearing() 中引用 SecureStorage 时,该应用不需要任何权利,但在主 App 类中定义的 TrySetAsync(...) 中引发了预期的异常。

有什么建议吗?

附:最初我在 OnAppearing() 中将 GetAsync 与随机 guid 字符串一起使用,我将其更改为 SetAsync 和 Remove,认为可能获取数据不需要兼容性。 总的来说,我从来没有遇到过 SecureStorage 这样的问题,而且这对我来说确实像是一些内部错误。\

回答

我不喜欢使用 string.Empty 作为值。看来 SecureStorage.SetAsync 将忽略此类值并且不存储它,这样就不会引发任何异常。此外,尝试从 SecureStorage 获取不存在的密钥也不会导致缺少授权异常

【问题讨论】:

  • 极不可能(我想说不可能)代码的位置允许使用不存在的权利。您观察到的症状很可能并不意味着权利有效。我不知道为什么没有抛出异常,但我会更彻底地测试。一个彻底的测试是将一个值存储到安全存储中,然后将其读回另一个变量中。使用 debug writelines 查看是否所有这些代码行都被执行,并查看从存储返回的值是否正确。
  • 预测:如果您在第一次调用securestorage 后有调试写入行,则该行将永远不会被执行。该 try 块中的任何以下行也不会。如果这个预测被证明是正确的,那么我们将调查这意味着什么。还要添加一个调试写入行作为catch 的第一行。如果 DisplayAlertOnAppearing 内部完成时失败,我不会感到惊讶。
  • 另外,您是否检查过 VS 输出窗格,看看在执行此代码时是否有任何警告或错误消息?
  • 嗨史蒂夫,很抱歉回复太长了,我今天只能坐下来。按照你的建议,我写了一个更完整的测试,我发现有两种情况没有抛出异常: 1. SetAsync 中的值是 string.Empty 或 null:app 忽略该值并且不存储它,没有异常被抛出。 2. GetAsync 引用的键目前在设备 KeyChain 上不存在:fetch 返回 null(如预期)并且不抛出异常。除了这两种情况,代码按预期工作。我很不幸(而且有点愚蠢)使用 string.Empty 而不是同时调用 Get 和 Set
  • 我将编辑我的原始问题以包含答案并将其作为问题报告给他们的 GitHub。感谢您的帮助

标签: xamarin xamarin.forms xamarin.ios xamarin.essentials


【解决方案1】:

(OP自己回答了这个问题):

我不喜欢使用 string.Empty 作为值。看来 SecureStorage.SetAsync 将忽略此类值并且不存储它,这样就不会引发任何异常。此外,尝试从 SecureStorage 获取不存在的密钥也不会导致缺少授权异常

【讨论】:

    猜你喜欢
    • 2023-03-13
    • 1970-01-01
    • 2018-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多