自定义指令以遮蔽敏感数据,同时保留原始值

huangapple go评论109阅读模式
英文:

custom directive to mask sensitive data while keeping the original value

问题

我需要编写一个指令,用于隐藏敏感数据(将中间部分替换为星号 '*')以供 ngModel 和 ngBind 使用,但我也需要保留原始的未屏蔽数据,以便将其发送回后端服务器。格式化部分不是问题,但我不知道如何保留原始数据。

我考虑过返回一个包含混淆和原始值的对象,但由于涉及到 ngBind,我不能依赖于 ngModelController 来设置格式化程序和解析器。

以下是我迄今为止的代码:

  1. app.factory('obfuscator', function() {
  2. return {
  3. obfuscate: obfuscate
  4. };
  5. function obfuscate(value) {
  6. // 假设未定义、空等情况都已经处理过
  7. let len = value.length;
  8. let chunk = Math.floor(len / 3);
  9. let masked = len - (chunk * 2);
  10. return {
  11. obfuscated: value.substr(0, chunk) + "*".repeat(masked) + value.substr(len - chunk, chunk),
  12. original: value
  13. };
  14. }
  15. }).directive('sensitive', ['obfuscator', function(obfuscator) {
  16. return {
  17. restrict: 'A',
  18. priority: 1,
  19. scope: {
  20. model: '=ngModel'
  21. },
  22. link: function(scope, element, attrs, controller) {
  23. scope.$watch('model', function() {
  24. if (angular.isUndefined(scope.model)) return;
  25. let val = obfuscator.obfuscate(scope.model);
  26. scope.model = val.obfuscated;
  27. });
  28. attrs.$observe('ngBind', function() {
  29. let val = obfuscator.obfuscate(element.text());
  30. element.text(val.obfuscated);
  31. });
  32. }
  33. }
  34. })]);

我的问题是:如何处理 val.original?如果我用 obfuscator.obfuscate() 返回的对象替换字段,我如何在我的控制器中检测到我的字段是否被修饰为 'sensitive',以便将 field.original 发送到后端服务器?我如何告诉视图在 ng-model="field" 中使用 "field.obfuscated" 而不是 "field"

英文:

Using: angularjs 1.4.

I need to write a directive that hides sensitive data (replacing the middle section with asterisk '*') for ngModel and ngBind, but I'd also need to keep the original, unmasked data in order to send it back to the backend server.

The formatting part is not a problem, but I don't know how to keep the original data.

I've thought of returning an object the with obfuscated and original values, but since ngBind is involved, I can't rely on ngModelController to set formatters and parsers.

Here's the code I have so far:

  1. app.factory('obfuscator', function() {
  2. return {
  3. obfuscate: obfuscate
  4. };
  5. function obfuscate(value) {
  6. // assume undef, empty, etc have all been taken care of
  7. let len = value.length;
  8. let chunk = Math.floor(len / 3);
  9. let masked = len - (chunk * 2);
  10. return {
  11. obfuscated: value.substr(0, chunk) + "*".repeat(masked) + value.substr(len - chunk, chunk),
  12. original: value
  13. };
  14. }
  15. }).directive('sensitive', ['obfuscator', function(obfuscator) {
  16. return {
  17. restrict: 'A',
  18. priority: 1,
  19. scope: {
  20. model: '=ngModel'
  21. },
  22. link: function(scope, element, attrs, controller) {
  23. scope.$watch('model', function() {
  24. if (angular.isUndefined(scope.model)) return;
  25. let val = obfuscator.obfuscate(scope.model);
  26. scope.model = val.obfuscated;
  27. });
  28. attrs.$observe('ngBind', function() {
  29. let val = obfuscator.obfuscate(element.text());
  30. element.text(val.obfuscated);
  31. });
  32. }
  33. }
  34. )]};

My question is: what to do with val.original?! If I replace the field with the object returned by obfuscator.obfuscate(), how can I detect that my field is decorated with 'sensitive' in my controller, in order to send field.original to the backend server? And how do I tell the view to use "field.obfuscated" instead of "field" in ng-model="field"?

答案1

得分: 0

I solved the issue by using two directives, 'sensitive' for ngBind and 'obfuscated' for ngModel. Not 100% satisfied with this solution, as this means it'll be necessary for others and me to remember which directive to use for ng-model and for 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);

  1. return val.substr(0, chunk) + "*".repeat(masked) + val.substr(len - chunk, chunk);
  2. }
  3. 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));

  1. controller.$parsers.shift((value) => {
  2. element.text(obfuscator.obfuscate(value));
  3. return value;
  4. });
  5. }

}
}]);

英文:

So I solved the issue by using two directives, 'sensitive' for ngBind and 'obfuscated' for ngModel. Not 100% satisfied with this solution, as this means it'll be necessary for others and me to remember which directive to use for ng-model and for ng-bind...

  1. app.factory('obfuscator', function() {
  2. return {
  3. obfuscate: obfuscate
  4. };
  5. function obfuscate(value) {
  6. if (value) {
  7. let val = value.toString(); // now can be called on numbers too...
  8. let len = val.length;
  9. let chunk = Math.floor(len / 3);
  10. let masked = len - (chunk * 2);
  11. return val.substr(0, chunk) + "*".repeat(masked) + val.substr(len - chunk, chunk);
  12. }
  13. return value;
  14. }
  15. }).directive('sensitive', ['obfuscator', function(obfuscator) {
  16. // directive for
  17. return {
  18. restrict: 'A',
  19. priority: 1,
  20. link: function(scope, element, attrs) {
  21. attrs.$observe('ngBind', function() {
  22. element.text(obfuscator.obfuscate(element.text()));
  23. });
  24. }
  25. }
  26. }]).directive('obfuscated', ['obfuscator', function(obfuscator) {
  27. return {
  28. restrict: 'A',
  29. priority: 1,
  30. require: 'ngModel',
  31. link: function(scope, element, attrs, controller) {
  32. controller.$formatters.push((value) => obfuscator.obfuscate(value));
  33. controller.$parsers.shift((value) => {
  34. element.text(obfuscator.obfuscate(value));
  35. return value;
  36. });
  37. }
  38. }
  39. }]);

答案2

得分: 0

以下是翻译好的内容:

最终成功找到了一个令人满意的解决方案。原来,在 require 前加上 ? 就可以使其成为可选的...所以我仍然可以在之后使用相同的指令:

  1. app.factory('obfuscator', function() {
  2. return {
  3. obfuscate: obfuscate
  4. };
  5. function obfuscate(value) {
  6. if (value) {
  7. let val = value.toString(); // 现在也可以用于数字了...
  8. let len = val.length;
  9. let chunk = Math.floor(len / 3);
  10. let masked = len - (chunk * 2);
  11. return val.substr(0, chunk) + "*".repeat(masked) + val.substr(len - chunk, chunk);
  12. }
  13. return value;
  14. }
  15. }).directive('sensitive', ['obfuscator', function(obfuscator) {
  16. return {
  17. restrict: 'A',
  18. priority: 1,
  19. require: '?ngModel', // 现在它是可选的了!
  20. link: function(scope, element, attrs, controller) {
  21. attrs.$observe('ngBind', function() {
  22. element.text(obfuscator.obfuscate(element.text()));
  23. });
  24. if (controller) {
  25. controller.$formatters.push((value) => obfuscator.obfuscate(value));
  26. controller.$parsers.shift((value) => {
  27. element.text(obfuscator.obfuscate(value));
  28. return value;
  29. });
  30. }
  31. }
  32. }
  33. }]);
英文:

finally was able to find a satisfying solution. Turns out require is optional if you precede it with ?... So I can use the same directive after all:

  1. app.factory('obfuscator', function() {
  2. return {
  3. obfuscate: obfuscate
  4. };
  5. function obfuscate(value) {
  6. if (value) {
  7. let val = value.toString(); // now can be called on numbers too...
  8. let len = val.length;
  9. let chunk = Math.floor(len / 3);
  10. let masked = len - (chunk * 2);
  11. return val.substr(0, chunk) + "*".repeat(masked) + val.substr(len - chunk, chunk);
  12. }
  13. return value;
  14. }
  15. }).directive('sensitive', ['obfuscator', function(obfuscator) {
  16. return {
  17. restrict: 'A',
  18. priority: 1,
  19. require: '?ngModel', // now it's optional!
  20. link: function(scope, element, attrs, controller) {
  21. attrs.$observe('ngBind', function() {
  22. element.text(obfuscator.obfuscate(element.text()));
  23. });
  24. if (controller) {
  25. controller.$formatters.push((value) => obfuscator.obfuscate(value));
  26. controller.$parsers.shift((value) => {
  27. element.text(obfuscator.obfuscate(value));
  28. return value;
  29. });
  30. }
  31. }
  32. }
  33. }]);

huangapple
  • 本文由 发表于 2020年1月6日 23:00:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/59614340.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定