React 集成jsoneditor后,password格式保护json数据的敏感信息
目录1.集成jsoneditor到React2.修改代码(1).添加Option(2).修改Node.js文件(3).修改util.js文件1.集成jsoneditor到React关于怎样将jsoneditor集成到React中,请参考文章:https://blog.csdn.net/wdquan19851029/article/details/115869264,本文只讲怎样修改jsonedit
目录
1.集成jsoneditor到React
关于怎样将jsoneditor集成到React中,请参考文章:https://blog.csdn.net/wdquan19851029/article/details/115869264,本文只讲怎样修改jsoneditor源码,使用password格式保护json敏感信息。
从github下载源代码:https://github.com/josdejong/jsoneditor
2.修改代码
我们得考虑,真正使用的时候,我们一般只是需要保护部分敏感信息,没有必要保护所有信息,那样根本什么信息都看不到,所以我们只考虑保护部分信息。
看我们的json数据,其中有需要保护的数据 "sensitive-data".
const initialJson = {
"Array": [1, 2, 3],
"Boolean": true,
"Null": null,
"Number": 123,
"Object": {"a": "b", "c": "d"},
"MultiLevel":{
"multi":{
"e": "f",
"h": "h"
}
},
"String": "Hello World",
"sensitive-data": {
"sensitive1": "sensitive1",
"sensitive2": "sensitive2",
"sensitive3": "sensitive3"
}
}
(1).添加Option
需要保护的信息,我们设计以option的形式传进去。我们自己添加一个新的参数sensitiveDataLabel ,设置其值为"sensitive-data"
const options = {
mode: 'tree',
sensitiveDataLabel: 'sensitive-data',
onChangeJSON: (data)=>{
console.log('JSONeditor:change:',data);}
}
(2).修改Node.js文件
然后修改Node.js的_createDomValue ()函数:其中注释为"新增的代码",是我做的修改,主要是判断parent node的name是不是与我们传进来的option sensitiveDataLabel 相等,如果相等,那么就创建一个input标签,type为password,用来保护敏感信息。
/**
* Create an editable value
* @private
*/
_createDomValue () {
let domValue
if (this.type === 'array') {
domValue = document.createElement('div')
domValue.textContent = '[...]'
} else if (this.type === 'object') {
domValue = document.createElement('div')
domValue.textContent = '{...}'
} else {
if (!this.editable.value && isUrl(this.value)) {
// create a link in case of read-only editor and value containing an url
domValue = document.createElement('a')
domValue.href = this.value
domValue.innerHTML = this._escapeHTML(this.value)
} else {
// create an editable or read-only div
//新增的代码
let isSensitiveData = false
//判断是否敏感数据方式1,只看当前node的parent,这是不合适的,因为可能有嵌套
//if(this.parent) {
//let sensitiveDataLabel = ""
//if(this.editor.options.sensitiveDataLabel) sensitiveDataLabel = this.editor.options.sensitiveDataLabel
//if(this.parent.getName() && this.parent.getName() == sensitiveDataLabel){
//isSensitiveData = true
//}
//}
//判断是否敏感数据方式2,因为敏感数据也有可能嵌套,所以不能只看当前node的parent,而要看其所有的json路径
let nodePaths = this.getNodePath()
let sensitiveDataLabel = ""
if(this.editor.options.sensitiveDataLabel) sensitiveDataLabel = this.editor.options.sensitiveDataLabel
for(var i = 0; i < nodePaths.length; i++) {
if(nodePaths[i].field && nodePaths[i].field == sensitiveDataLabel){
isSensitiveData = true
break;
}
}
if(isSensitiveData){
//新增的代码
domValue = document.createElement('input')
domValue.type = "password"
domValue.placeholder=""
domValue.autocomplete = "new-password" //防止自动填充保存过的登录密码
domValue.style.border = "none" //去掉输入框的边框
domValue.contentEditable = this.editable.value
domValue.spellcheck = false
domValue.value = this._escapeHTML(this.value)
}else{
domValue = document.createElement('div')
domValue.contentEditable = this.editable.value
domValue.spellcheck = false
domValue.innerHTML = this._escapeHTML(this.value)
}
}
}
return domValue
}
重新编译源代码,并导入React工程之后,可以看到效果:
(3).修改util.js文件
但是当进行修改的时候,发现修改无效,头疼,继续修改代码,修改util.js文件中的getInnerText (element, buffer)函数。
注释为"新增的代码"部分,就是我做的修改,将用户在上面界面的修改,赋给child这个Node,因为以前都是用<div>标签去显示value,现在改成了<input>,按照以前的方式,是用innerHTML属性获取值,但是现在需要使用value属性去获取值。
export function getInnerText (element, buffer) {
const first = (buffer === undefined)
if (first) {
buffer = {
_text: '',
flush: function () {
const text = this._text
this._text = ''
return text
},
set: function (text) {
this._text = text
}
}
}
// text node
//console.log("Debug: getInnerText() -> element.nodeValue : " + element.nodeValue)
if (element.nodeValue) {
// remove return characters and the whitespace surrounding return characters
const trimmedValue = element.nodeValue.replace(/\s*\n\s*/g, '')
if (trimmedValue !== '') {
return buffer.flush() + trimmedValue
} else {
// ignore empty text
return ''
}
}
// divs or other HTML elements
if (element.hasChildNodes()) {
const childNodes = element.childNodes
let innerText = ''
for (let i = 0, iMax = childNodes.length; i < iMax; i++) {
const child = childNodes[i]
//新增的代码
if(element.type == "password" && element.value){
child.nodeValue = element.value;
}
if (child.nodeName === 'DIV' || child.nodeName === 'P') {
const prevChild = childNodes[i - 1]
const prevName = prevChild ? prevChild.nodeName : undefined
if (prevName && prevName !== 'DIV' && prevName !== 'P' && prevName !== 'BR') {
if (innerText !== '') {
innerText += '\n'
}
buffer.flush()
}
innerText += getInnerText(child, buffer)
buffer.set('\n')
} else if (child.nodeName === 'BR') {
innerText += buffer.flush()
buffer.set('\n')
} else {
innerText += getInnerText(child, buffer)
}
}
return innerText
}
// br or unknown
return ''
}
3.扩展:
如果除了"sensitive-data"数据,还有别的数据需要保护,怎么办? 其实非常简单,传参数的时候,传入一个数组 sensitiveDataLabel: ['sensitive-data', 'sensitive-data1', 'sensitive-data2'],然后在Node.js中判断的时候,将if(nodePaths[i].field && nodePaths[i].field == sensitiveDataLabel) 改为if(nodePaths[i].field && sensitiveDataLabel.indexOf(nodePaths[i].field) > -1),大体就是这样子,有需要的话,请自己进行修改。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)