我创建了一个聊天页面,登录用户应该只能通过单个目标看到他自己的消息。但是,每个用户都可以看到每个其他用户所谓的自发(循环)消息。每个登录用户发送他自己的 JWT:
$this->denyAccessUnlessGranted('ROLE_USER');
$user = $this->getUser();
$userid = $user->getId();
$pass = $user->getPassword();
$token = (new Builder())
// set other appropriate JWT claims, such as an expiration date
->set('mercure', ['subscribe' => ["http://localhost:8000/user/".$userid],'publish' => ["http://localhost:8000/user/".$userid]]) // could also include the security roles, or anything else
->sign(new Sha256(), 'K3y')
->getToken();
return $this->render('chat/index.html.twig', [
'config' => [
'topic' => 'chat',
'publishRoute' => $this->generateUrl('publisher', ['topic' => 'chat'])
], 'token' => $token
]);
用户聊天页面的JS是这样的:
<script src="js/eventsource.min.js"></script>
<script>
const {topic, publishRoute} = JSON.parse(document.getElementById('config').textContent);
const subscribeURL = new URL('http://localhost:3000/.well-known/mercure');
subscribeURL.searchParams.append('topic', topic);
const es = new EventSourcePolyfill(subscribeURL, {
headers: {
'Authorization': 'Bearer ' + '{{ token }}',
}
});
let ul = null;
es.onmessage = ({data}) => {
const {username, message} = JSON.parse(data)
if (!username || !message)
throw new Error('Invalid payload')
if (!ul) {
ul = document.createElement('ul');
const messages = document.getElementById('messages');
messages.innerHTML = '';
messages.append(ul);
}
const li = document.createElement('li')
li.append(document.createTextNode(`<${username}> ${message}`))
ul.append(li)
};
document.querySelector('form').onsubmit = function (e) {
e.preventDefault();
fetch(publishRoute, {method: 'POST', body: JSON.stringify({username: this.elements.username.value, message: this.elements.message.value})});
this.elements.message.value = '';
this.elements.message.focus();
}
</script>
登录后,聊天页面的 URL 为http://localhost:8000/chat 。
我的 Mercure hub 的参数是这样的:
$env:JWT_KEY='K3y'; $env:ADDR='localhost:3000'; $env:ALLOW_ANONYMOUS='0'; $env:CORS_ALLOWED_ORIGINS='http://localhost:8000'; $env:PUBLISH_ALLOWED_ORIGINS='http://localhost:3000'; .\mercure.exe
请帮忙!我使用了每个用户的 JWT,但是隔离更新的安全性不起作用:/