自定义指令在保持原始值的同时屏蔽敏感数据
custom directive to mask sensitive data while keeping the original value
使用:angularjs 1.4.
我需要为 ngModel 和 ngBind 编写隐藏敏感数据的指令(用星号“*”替换中间部分),但我还需要保留原始的、未屏蔽的数据以便将其发回到后端服务器。
格式化部分没有问题,但不知道如何保留原始数据。
我想过返回一个带有混淆值和原始值的对象,但由于涉及到 ngBind,我不能依赖 ngModelController 来设置格式化程序和解析器。
这是我目前的代码:
app.factory('obfuscator', function() {
return {
obfuscate: obfuscate
};
function obfuscate(value) {
// assume undef, empty, etc have all been taken care of
let len = value.length;
let chunk = Math.floor(len / 3);
let masked = len - (chunk * 2);
return {
obfuscated: value.substr(0, chunk) + "*".repeat(masked) + value.substr(len - chunk, chunk),
original: value
};
}
}).directive('sensitive', ['obfuscator', function(obfuscator) {
return {
restrict: 'A',
priority: 1,
scope: {
model: '=ngModel'
},
link: function(scope, element, attrs, controller) {
scope.$watch('model', function() {
if (angular.isUndefined(scope.model)) return;
let val = obfuscator.obfuscate(scope.model);
scope.model = val.obfuscated;
});
attrs.$observe('ngBind', function() {
let val = obfuscator.obfuscate(element.text());
element.text(val.obfuscated);
});
}
}
)]};
我的问题是:如何处理 val.original?!如果我用 obfuscator.obfuscate()
返回的对象替换字段,我如何检测我的字段在我的控制器中用 'sensitive' 装饰,以便将 field.original 发送到后端服务器?我如何告诉视图在 ng-model="field"
中使用 "field.obfuscated" 而不是 "field"?
所以我通过使用两个指令解决了这个问题,'sensitive' 用于 ngBind,'obfuscated' 用于 ngModel。对这个解决方案不是 100% 满意,因为这意味着其他人和我有必要记住哪个指令用于 ng-model 和 ng-bind...
app.factory('obfuscator', function() {
return {
obfuscate: obfuscate
};
function obfuscate(value) {
if (value) {
let val = value.toString(); // now can be called on numbers too...
let len = val.length;
let chunk = Math.floor(len / 3);
let masked = len - (chunk * 2);
return val.substr(0, chunk) + "*".repeat(masked) + val.substr(len - chunk, chunk);
}
return value;
}
}).directive('sensitive', ['obfuscator', function(obfuscator) {
// directive for
return {
restrict: 'A',
priority: 1,
link: function(scope, element, attrs) {
attrs.$observe('ngBind', function() {
element.text(obfuscator.obfuscate(element.text()));
});
}
}
}]).directive('obfuscated', ['obfuscator', function(obfuscator) {
return {
restrict: 'A',
priority: 1,
require: 'ngModel',
link: function(scope, element, attrs, controller) {
controller.$formatters.push((value) => obfuscator.obfuscate(value));
controller.$parsers.shift((value) => {
element.text(obfuscator.obfuscate(value));
return value;
});
}
}
}]);
终于找到满意的解决方案了。结果 require
是可选的,如果你在它前面加上 ?
... 所以我毕竟可以使用相同的指令:
app.factory('obfuscator', function() {
return {
obfuscate: obfuscate
};
function obfuscate(value) {
if (value) {
let val = value.toString(); // now can be called on numbers too...
let len = val.length;
let chunk = Math.floor(len / 3);
let masked = len - (chunk * 2);
return val.substr(0, chunk) + "*".repeat(masked) + val.substr(len - chunk, chunk);
}
return value;
}
}).directive('sensitive', ['obfuscator', function(obfuscator) {
return {
restrict: 'A',
priority: 1,
require: '?ngModel', // now it's optional!
link: function(scope, element, attrs, controller) {
attrs.$observe('ngBind', function() {
element.text(obfuscator.obfuscate(element.text()));
});
if (controller) {
controller.$formatters.push((value) => obfuscator.obfuscate(value));
controller.$parsers.shift((value) => {
element.text(obfuscator.obfuscate(value));
return value;
});
}
}
}
}]);
使用:angularjs 1.4.
我需要为 ngModel 和 ngBind 编写隐藏敏感数据的指令(用星号“*”替换中间部分),但我还需要保留原始的、未屏蔽的数据以便将其发回到后端服务器。
格式化部分没有问题,但不知道如何保留原始数据。
我想过返回一个带有混淆值和原始值的对象,但由于涉及到 ngBind,我不能依赖 ngModelController 来设置格式化程序和解析器。
这是我目前的代码:
app.factory('obfuscator', function() {
return {
obfuscate: obfuscate
};
function obfuscate(value) {
// assume undef, empty, etc have all been taken care of
let len = value.length;
let chunk = Math.floor(len / 3);
let masked = len - (chunk * 2);
return {
obfuscated: value.substr(0, chunk) + "*".repeat(masked) + value.substr(len - chunk, chunk),
original: value
};
}
}).directive('sensitive', ['obfuscator', function(obfuscator) {
return {
restrict: 'A',
priority: 1,
scope: {
model: '=ngModel'
},
link: function(scope, element, attrs, controller) {
scope.$watch('model', function() {
if (angular.isUndefined(scope.model)) return;
let val = obfuscator.obfuscate(scope.model);
scope.model = val.obfuscated;
});
attrs.$observe('ngBind', function() {
let val = obfuscator.obfuscate(element.text());
element.text(val.obfuscated);
});
}
}
)]};
我的问题是:如何处理 val.original?!如果我用 obfuscator.obfuscate()
返回的对象替换字段,我如何检测我的字段在我的控制器中用 'sensitive' 装饰,以便将 field.original 发送到后端服务器?我如何告诉视图在 ng-model="field"
中使用 "field.obfuscated" 而不是 "field"?
所以我通过使用两个指令解决了这个问题,'sensitive' 用于 ngBind,'obfuscated' 用于 ngModel。对这个解决方案不是 100% 满意,因为这意味着其他人和我有必要记住哪个指令用于 ng-model 和 ng-bind...
app.factory('obfuscator', function() {
return {
obfuscate: obfuscate
};
function obfuscate(value) {
if (value) {
let val = value.toString(); // now can be called on numbers too...
let len = val.length;
let chunk = Math.floor(len / 3);
let masked = len - (chunk * 2);
return val.substr(0, chunk) + "*".repeat(masked) + val.substr(len - chunk, chunk);
}
return value;
}
}).directive('sensitive', ['obfuscator', function(obfuscator) {
// directive for
return {
restrict: 'A',
priority: 1,
link: function(scope, element, attrs) {
attrs.$observe('ngBind', function() {
element.text(obfuscator.obfuscate(element.text()));
});
}
}
}]).directive('obfuscated', ['obfuscator', function(obfuscator) {
return {
restrict: 'A',
priority: 1,
require: 'ngModel',
link: function(scope, element, attrs, controller) {
controller.$formatters.push((value) => obfuscator.obfuscate(value));
controller.$parsers.shift((value) => {
element.text(obfuscator.obfuscate(value));
return value;
});
}
}
}]);
终于找到满意的解决方案了。结果 require
是可选的,如果你在它前面加上 ?
... 所以我毕竟可以使用相同的指令:
app.factory('obfuscator', function() {
return {
obfuscate: obfuscate
};
function obfuscate(value) {
if (value) {
let val = value.toString(); // now can be called on numbers too...
let len = val.length;
let chunk = Math.floor(len / 3);
let masked = len - (chunk * 2);
return val.substr(0, chunk) + "*".repeat(masked) + val.substr(len - chunk, chunk);
}
return value;
}
}).directive('sensitive', ['obfuscator', function(obfuscator) {
return {
restrict: 'A',
priority: 1,
require: '?ngModel', // now it's optional!
link: function(scope, element, attrs, controller) {
attrs.$observe('ngBind', function() {
element.text(obfuscator.obfuscate(element.text()));
});
if (controller) {
controller.$formatters.push((value) => obfuscator.obfuscate(value));
controller.$parsers.shift((value) => {
element.text(obfuscator.obfuscate(value));
return value;
});
}
}
}
}]);