离子安全存储 - 要求用户设置锁定屏幕

Posted

技术标签:

【中文标题】离子安全存储 - 要求用户设置锁定屏幕【英文标题】:Ionic secure storage - Ask the user to set a lock screen 【发布时间】:2018-03-13 05:26:14 【问题描述】:

我正在尝试初始化安全存储插件。如果此操作失败,则意味着用户没有设置安全的锁屏。使用 github 页面,我正在尝试重新创建提供的示例:

var ss;
var _init = function () 
    ss = new cordova.plugins.SecureStorage(
        function () 
            console.log('OK');
        ,
        function () 
            navigator.notification.alert(
                'Please enable the screen lock on your device. This app cannot operate securely without it.',
                function () 
                    ss.secureDevice(
                        function () 
                            _init();
                        ,
                        function () 
                            _init();
                        
                    );
                ,
                'Screen lock is disabled'
            );
        ,
        'my_app');
;
_init();

这是我的尝试:

private createSecureStorage() 
    this.secureStorageAPI.create(this.storeName).then( 
        (storage: SecureStorageObject) => 
            this.secureStorage = storage;
    ).catch( 
        (error) => 
            this.dialogs.alert( 'Please enable the screen lock on your device. This app cannot operate securely without it.').then( 
                () => 
                // Alert Dismissed, should open the secure lockscreen settings here
                  this.secureStorage.secureDevice().then( 
                      () => 
                          // Try again
                          this.createSecureStorage();
                      
                  ).catch( () =>  
                    // Try again
                    this.createSecureStorage();
                  )
                )
       );
  

我遇到的问题是,当secureStorageApi.create 调用失败时,secureStorage 将未定义,因此我无法使用它来调用secureDevice()。

任何帮助将不胜感激。

【问题讨论】:

没有人能帮忙解决这个问题吗?我认为这可能是一个错误的设计,因为您需要 SecureStorage 对象才能调用 secureDevice() 【参考方案1】:

此问题已作为问题进行跟踪,请参阅:https://github.com/ionic-team/ionic-native/issues/1944。

如果您需要快速解决此问题,可以尝试以下步骤之一:

1) 降级 Ionic SecureStorage 插件,这个问题可能在以前的版本中不会出现。

2) 尝试自己解决问题。您可以在此处的 node_modules 文件夹中找到源代码(如果您需要帮助,我可以稍后再查看):

node_modules\cordova-plugin-secure-storage\src\android\SecureStorage.java node_modules\cordova-plugin-secure-storage\src\ios\SecureStorage.m

.

【讨论】:

谢谢!我找不到那个问题。我会尝试自己修改插件。如果我有任何问题,我会告诉你。 经过一番研究,我设法解决了这个问题。我会做一些广泛的测试,然后在这里发布代码。【参考方案2】:

对于现在需要此功能的所有人进行修改:

node_modules\@ionic-native\secure-storage\index.js

工作代码

应该是这样的:

 var __extends = (this && this.__extends) || (function () 
    var extendStatics = Object.setPrototypeOf ||
        ( __proto__: []  instanceof Array && function (d, b)  d.__proto__ = b; ) ||
        function (d, b)  for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; ;
    return function (d, b) 
        extendStatics(d, b);
        function __()  this.constructor = d; 
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    ;
)();
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) 
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
;
var __metadata = (this && this.__metadata) || function (k, v) 
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
;
import  Injectable  from '@angular/core';
import  CordovaInstance, Plugin, CordovaCheck, IonicNativePlugin  from '@ionic-native/core';
/**
 * @hidden
 */
var SecureStorageObject = (function () 
    function SecureStorageObject(_objectInstance) 
        this._objectInstance = _objectInstance;
    
    /**
     * Gets a stored item
     * @param key string
     * @returns Promise<string>
     */
    SecureStorageObject.prototype.get = function (key)  return; ;
    /**
     * Stores a value
     * @param key string
     * @param value string
     * @returns Promise<any>
     */
    SecureStorageObject.prototype.set = function (key, value)  return; ;
    /**
     * Removes a single stored item
     * @param key string
     * @returns Promise<string> returns a promise that resolves with the key that was removed
     */
    SecureStorageObject.prototype.remove = function (key)  return; ;
    /**
     * Get all references from the storage.
     * @returns Promise<string[]> returns a promise that resolves with array of keys storage
     */
    SecureStorageObject.prototype.keys = function ()  return; ;
    /**
     * Clear all references from the storage.
     * @returns Promise<any>
     */
    SecureStorageObject.prototype.clear = function ()  return; ;
    return SecureStorageObject;
());
/**
 * @hidden
 */
var SecureDeviceObject = (function () 
    function SecureDeviceObject(_objectInstance) 
        this._objectInstance = _objectInstance;
    

    /**
        * Brings up the screen-lock settings
        * @returns Promise<any>
        */
    SecureStorageObject.prototype.secureDevice = function ()  return; ;
    return SecureDeviceObject;
());
export  SecureStorageObject, SecureDeviceObject ;
__decorate([
    CordovaInstance(
        callbackOrder: 'reverse'
    ),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], SecureStorageObject.prototype, "get", null);
__decorate([
    CordovaInstance(
        callbackOrder: 'reverse'
    ),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String]),
    __metadata("design:returntype", Promise)
], SecureStorageObject.prototype, "set", null);
__decorate([
    CordovaInstance(
        callbackOrder: 'reverse'
    ),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], SecureStorageObject.prototype, "remove", null);
__decorate([
    CordovaInstance(
        callbackOrder: 'reverse'
    ),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], SecureStorageObject.prototype, "keys", null);
__decorate([
    CordovaInstance(
        callbackOrder: 'reverse'
    ),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], SecureStorageObject.prototype, "clear", null);
__decorate([
    CordovaInstance(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], SecureDeviceObject.prototype, "secureDevice", null);
/**
 * @name Secure Storage
 * @description
 * This plugin gets, sets and removes key,value pairs from a device's secure storage.
 *
 * Requires Cordova plugin: `cordova-plugin-secure-storage`. For more info, please see the [Cordova Secure Storage docs](https://github.com/Crypho/cordova-plugin-secure-storage).
 *
 * The browser platform is supported as a mock only. Key/values are stored unencrypted in localStorage.
 *
 * @usage
 *
 * ```typescript
 * import  SecureStorage, SecureStorageObject  from '@ionic-native/secure-storage';
 *
 * constructor(private secureStorage: SecureStorage)  
 *
 * ...
 *
 * this.secureStorage.create('my_store_name')
 *   .then((storage: SecureStorageObject) => 
 *
 *      storage.get('key')
 *        .then(
 *          data => console.log(data),
 *          error => console.log(error)
 *      );
 *
 *      storage.set('key', 'value')
 *        .then(
 *         data => console.log(data),
 *          error => console.log(error)
 *      );
 *
 *      storage.remove('key')
 *      .then(
 *          data => console.log(data),
 *          error => console.log(error)
 *      );
 *
 *   );
 *
 *
 * ```
 * @classes
 * SecureStorageObject
 */
var SecureStorage = SecureStorage_1 = (function (_super) 
    __extends(SecureStorage, _super);
    function SecureStorage() 
        return _super !== null && _super.apply(this, arguments) || this;
    
    /**
     * Creates a namespaced storage.
     * @param store string
     * @returns Promise<SecureStorageObject>
     */
    SecureStorage.prototype.create = function (store) 
        return new Promise(function (res, rej) 
            var instance = new (SecureStorage_1.getPlugin())(
                function ()  
                    res(new SecureStorageObject(instance)); 
                , 
                function () 
                    rej(new SecureDeviceObject(instance));
                , 
                store);
        );
    ;
    return SecureStorage;
(IonicNativePlugin));
SecureStorage.decorators = [
     type: Injectable ,
];
/** @nocollapse */
SecureStorage.ctorParameters = function ()  return []; ;
__decorate([
    CordovaCheck(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], SecureStorage.prototype, "create", null);
SecureStorage = SecureStorage_1 = __decorate([
    Plugin(
        pluginName: 'SecureStorage',
        plugin: 'cordova-plugin-secure-storage',
        pluginRef: 'cordova.plugins.SecureStorage',
        repo: 'https://github.com/Crypho/cordova-plugin-secure-storage',
        platforms: ['Android', 'Browser', 'iOS', 'Windows']
    )
], SecureStorage);
export  SecureStorage ;
var SecureStorage_1;
//# sourceMappingURL=index.js.map

然后你就可以使用了:

 private createSecureStorage() 
        this.secureStorageAPI.create(this.storeName).then( 
            (storage: SecureStorageObject) => 
                console.log("secure");
                this.secureStorage = storage;
        ).catch( 
            (secureDeviceObject) => 
                this.dialogs.alert( 'Please enable the screen lock on your device. This app cannot operate securely without it.').then( 
                    () => 
                        // Alert Dismissed, should open the secure lockscreen settings here
                        secureDeviceObject.secureDevice().then( 
                        () => 
                            // Try again
                            console.log("Success");
                            this.createSecureStorage();
                         ).catch( () =>  
                            // Try again
                            console.log(" Error ")
                            this.createSecureStorage();
                        )
                     ); 
             );
    

发生了什么变化?

我所做的是将secureDevice 函数移动到一个名为SecureDeviceObject 的新对象并更改了装饰器。通过这样做,您不能使用此对象来尝试调用 get 和 set 函数等。

这是新对象:

var SecureDeviceObject = (function () 
    function SecureDeviceObject(_objectInstance) 
        this._objectInstance = _objectInstance;
    

    /**
        * Brings up the screen-lock settings
        * @returns Promise<any>
        */
    SecureStorageObject.prototype.secureDevice = function ()  return; ;
    return SecureDeviceObject;
());

然后我改变了装饰器:

__decorate([
    CordovaInstance(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], SecureDeviceObject.prototype, "secureDevice", null);

最后的改变是让拒绝承诺返回secureDeviceObject:

SecureStorage.prototype.create = function (store) 
        return new Promise(function (res, rej) 
            var instance = new (SecureStorage_1.getPlugin())(
                function ()  
                    res(new SecureStorageObject(instance)); 
                , 
                function () 
                    rej(new SecureDeviceObject(instance));
                , 
                store);
        );
    ;

我想这不是最好的解决方法,但这是我能做的最好的:D 在 android 4 到 8 上测试。正在处理所有这些问题!

希望它可以帮助某人:)

感谢@JudgeFudge 为我指明了正确的方向

【讨论】:

嘿,干得好,你能用你的代码关闭这个错误吗? :) github.com/ionic-team/ionic-native/issues/1625【参考方案3】:

Here 我发送了一个拉取请求来修复这个错误。

这里:

create(store: string): Promise<SecureStorageObject> 
    return getPromise<SecureStorageObject>((res: Function, rej: Function) => 
        const instance = new (SecureStorage.getPlugin())(
            () => res(new SecureStorageObject(instance)),
            rej,
            store
        );
    );

简单更改拒绝回调:

() => rej(new SecureStorageObject(instance)),

内部ionic-native/src/@ionic-native/plugins/secure-storage/index.ts

然后:

npm install npm run build

最后复制在你的 npm_modules 文件夹中编译的插件:

cp -r ionic-native/dist/@ionic-native/plugins/secure-storage/ /your_project/node_modules/@ionic-native/ 更新:

他们合并 PR。

这里如何使用它:

this.storage = await this.secureStorage.create('my_storage'); catch (e) await e.secureDevice();

【讨论】:

ionic 合并了 Pull Request @ionic-native 上缺少文档,这意味着这是最好的文档:try this.storage = await this.secureStorage.create('my_storage'); 捕捉 (e) 等待 e.secureDevice(); 谢谢。我还为 @ionic-native/plugins/secure-storage-echo 做了一个 PR(合并)

以上是关于离子安全存储 - 要求用户设置锁定屏幕的主要内容,如果未能解决你的问题,请参考以下文章

在我的应用中使用屏幕锁定

电脑上的时间被锁定了 修改不来怎么回事??

如何在离子应用程序中将图像设置为墙纸?

pixel去除锁定图案

从主屏幕检测密码锁定状态

Win10 如何设置自动锁定屏幕