修复了发送文本消息会产生xss攻击的问题

master
cleverqin 4 years ago
parent 03c083fdc3
commit 53ec51d8f7

@ -93,7 +93,7 @@ io.sockets.on('connection',(socket)=>{
//删除登录用户信息,并通知所有在线用户
util.removeUser(socket.user.id);
socket.broadcast.emit('system', socket.user, 'logout');
store.saveUser(user,"logout");
store.saveUser(socket.user,"logout");
}
});
let userJson=socket.handshake.query.User;

@ -252,10 +252,36 @@ html,body{
.message-item-send .message-content-container{
background-color: #0087f7;
color: #f2f2f2;
position: relative;
}
.message-item-send .message-content-container:after{
display: block;
content: '';
position: absolute;
border-top: 5px solid transparent;
border-bottom: 5px solid transparent;
border-left: 5px solid #0087f7;
top: 15px;
left: 100%;
}
.message-item-receive .message-content-container{
position: relative;
background-color: #ffffff;
color: #606266;
}
.message-item-receive .message-avatar{
float: left;
}
.message-item-receive .message-content-container:before{
display: block;
content: '';
position: absolute;
border-top: 5px solid transparent;
border-bottom: 5px solid transparent;
border-right: 5px solid #ffffff;
top: 15px;
right: 100%;
}
/****用户组件样式****/
.user-item-avatar{
display: block;

@ -44,7 +44,9 @@
:num="getUnReadNum(item.id)"
:key="item.id">
<div slot="time" v-if="getLatestMessage(item.id).time">{{getLatestMessage(item.id).time | friendlyTime}}</div>
<span slot="message" v-if="getLatestMessage(item.id).type==='text'" v-html="renderExpression(getLatestMessage(item.id).content,baseUrl)"></span>
<span slot="message" v-if="getLatestMessage(item.id).type==='text'">
<message-text :text="getLatestMessage(item.id).content"></message-text>
</span>
<div slot="message" v-if="getLatestMessage(item.id).type==='image'">【图片】</div>
</user-item>
</div>
@ -61,7 +63,9 @@
<div class="webChat-session-messages">
<div class="webChat-message-list scroll" ref="message-list">
<message-item v-for="(item,i) in messages" :is-send="loginUser.id===item.from.id" :setting="setting" :key="i" :message="item">
<div class="message-content-container" v-html="renderExpression(item.content,baseUrl)" slot="message" v-if="item.type==='text'"></div>
<div class="message-content-container" slot="message" v-if="item.type==='text'">
<message-text :text="item.content"></message-text>
</div>
<div class="message-image-warp" slot="message" v-if="item.type==='image'" v-html="item.content"></div>
</message-item>
</div>
@ -272,7 +276,9 @@
:num="getUnReadNum(item.id)"
:key="item.id">
<div slot="time" v-if="getLatestMessage(item.id).time">{{getLatestMessage(item.id).time | friendlyTime}}</div>
<span slot="message" v-if="getLatestMessage(item.id).type==='text'" v-html="renderExpression(getLatestMessage(item.id).content,baseUrl)"></span>
<span slot="message" v-if="getLatestMessage(item.id).type==='text'">
<message-text :text="getLatestMessage(item.id).content"></message-text>
</span>
<div slot="message" v-if="getLatestMessage(item.id).type==='image'">【图片】</div>
</user-item>
</div>
@ -385,7 +391,9 @@
<div class="iChat-session-container" :class="{'with-panel':isShowTool||isShowExpression}">
<div class="iChat-message-list scroll" ref="message-list">
<message-item v-for="(item,i) in messages" :is-send="loginUser.id===item.from.id" :setting="setting" :key="i" :message="item">
<div class="message-content-container" v-html="renderExpression(item.content,baseUrl)" slot="message" v-if="item.type==='text'"></div>
<div class="message-content-container" slot="message" v-if="item.type==='text'">
<message-text :text="item.content"></message-text>
</div>
<div class="message-image-warp" slot="message" v-if="item.type==='image'" v-html="item.content"></div>
</message-item>
</div>

@ -346,27 +346,40 @@
{title:"[飞机]",url: "/飞机.gif"},
{title:"[气球]",url: "/气球.gif"}
];
//渲染解析表情
const renderExpression=function(text,baseUrl){
let expressionMap={};
expressions.forEach((item,i)=>{
expressionMap[item.title]=i;
let mapData=[];
expressions.forEach((item)=>{
mapData[item.title]=item.url;
});
if(typeof (text) != "undefined") {
let arr = text.match(/\[.*?\]/g);
if(arr&&arr.length>0){
for(let i = 0; i < arr.length; i++){
let index=expressionMap[arr[i]];
if(index!==undefined) {
let url=baseUrl+expressions[index].url;
const img = "<img src="+url +" class='expression-img'/>";
text = text.replace(arr[i],img);
//渲染解析表情
const MessageText=Vue.extend({
props:{
text:{
type:String,
default:""
}
},
render(h){
const reg=/\[.*?\]/g;
let result=this.text.replace(reg,(word)=>{
return "|"+word+"|";
});
let arr=result.split('|');
return h('span',
arr.map((item)=>{
if(reg.test(item)&&mapData[item]){
return h('img',{
class:"expression-img",
attrs:{
src:mixin.data().baseUrl+mapData[item]
}
})
}else {
return item;
}
})
)
}
return text;
};
});
//消息组件
const MessageItem=Vue.extend({
template:"#message-item",
@ -531,7 +544,7 @@
new Vue({
template: mainTpl,
el:"#app",
components:{MessageItem,UserItem,Login},
components:{MessageItem,UserItem,Login,MessageText},
mixins:[mixin],
data(){
return {
@ -560,7 +573,6 @@
pickerExpression(item){
this.text+=item.title;
},
renderExpression,
fileChange(e){
let file=e.target.files[0];
let maxSize=1*1024*1024;
@ -639,7 +651,7 @@
_this.socket.on("loginSuccess",(user,users)=>{
_this.loginUser=user;
_this.onlineUsers=users;
document.title="聊天室 | "+user.name;
document.title=user.name+" 聊天室";
});
_this.socket.on("loginFail",(message)=>{
AlterMessage(message,'error')

Loading…
Cancel
Save