Symfony Websockets:记录的用户总是 returns 主题内的匿名
Symfony Websockets: Logged User always returns anonym within Topic
I finally found the problem - but can't explain it well. The Webserver and Websocket Server are running on "127.0.0.1:xyz" each. When I access my website with "127.0.0.1:xy/app_dev.php/account" , everything is working, cookies are sent, read and the logged in user is given back by the clientManipulator.
When I access my website with "localhost:xy/app_dev.php/account", I always get back an anonymous user and the cookies are not sent. Can someone explain this to me please - and will this have affects in production mode too ? (e.g. a user can also connect with the IP of the website - and then this would bring me to the same problem, wouldn't it ? )
此问题与 this one 有关。 (Symfony 2.7)
我已经实现了 Gos Websocket Bundle,现在可以将消息实时发送到用户可以订阅的频道。当前的问题是,我无法访问我的通知主题 class 中当前登录的用户。我已经尝试了在我链接到的相关 post 中订阅的所有内容。
目前,我正在将“@security.token_storage”注入到我的主题中——但正如我所说,其他方法的行为也相同。我认为这是一个 "cookie / domain" 问题,cookie 没有发送到 websocket 服务器。这是我的配置:
Symfony / php 网络服务器: "Server running on http://127.0.0.1:8000"
Gos websocketconfig.yml:
gos_web_socket:
server:
port: 8081 #The port the socket server will listen on
host: 127.0.0.1 #The host ip to bind to
router:
resources:
- @MessageBundle/Resources/config/pubsub/routing.yml
client:
firewall: main
session_handler: @session.handler.pdo
pushers:
zmq:
host: 127.0.0.1
port: 5555
persistent: true
protocol: tcp
@session.handler.pdo 在 services.yml:
pdo:
class: PDO
arguments:
dsn: mysql:host=%database_host%;port=%database_port%;dbname=%database_name%
user: %database_user%
password: %database_password%
calls:
- [ setAttribute, [3, 2] ] # \PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION
session.handler.pdo:
class: Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler
arguments: [@pdo, {lock_mode: 0}]
配置为使用 pdo 处理程序的框架会话:
session:
# handler_id set to null will use default session handler from php.ini
handler_id: session.handler.pdo
JavaScript 连接客户端与 websocket 的部分:
var webSocket = WS.connect("ws://127.0.0.1:8000");
webSocket.on("socket/connect", function(session){
session.subscribe("account/notification", function(uri, payload){
console.log("Received message", payload.msg);
});
});
这是我的配置,令牌存储被注入到通知主题的服务中。主题的 "onSubscribe" 方法被命中,但用户保持匿名,即使我已登录:
public function onSubscribe(ConnectionInterface $connection, Topic $topic, WampRequest $request)
{
// always returns anonym
dump($this->tokenStorage->getToken()->getUser());die;
}
我错过了什么?
此致。
为了在 web 应用程序和 websocket 之间共享会话,两者必须 运行 在同一域和同一端口上,否则浏览器将不会发送 cookie
Web app: http://www.exemple.com:80
Websocket: ws://ws.exemple.com:80
并且必须为域 exemple.com(没有任何子域)配置 cookie
当您的网络服务器 运行 在端口 8000
上时,您的配置似乎是针对 websocket 的端口 8081 设置的
希望对您有所帮助
现在很清楚了,解释在于 HTTP cookie 限制。在此处查找更多详细信息:http://www.cookiecentral.com/faq/#4.3
"The main limit on retrieving a cookie is that you can only retrieve cookies that are valid for the document your script resides in. That is, a script on www.myserver.com cannot read cookies from www.yourserver.com."
此外,我建议您确保 运行 将您的 websocket 服务器连接到 "localhost" 域,以便使用 "localhost" 访问您的网站。这样做,两个域仍然是一致的。
作为我自己的一个问题,我从未检查过通过其地址 (127.0.0.1) 访问该网站并在 "localhost" 上设置 websocket 服务器 运行 是否会触发相同的问题。无论如何,回答你,不,只要你有正确的域(不是 ip),这不应该在产品中重现一次。
但是,Thomas 的回答是不正确的,你不能 运行 两个服务器都在同一个端口上,因为它是端口的定义(一个端口,一个 service/process):https://en.wikipedia.org/wiki/Port_%28computer_networking%29.
I finally found the problem - but can't explain it well. The Webserver and Websocket Server are running on "127.0.0.1:xyz" each. When I access my website with "127.0.0.1:xy/app_dev.php/account" , everything is working, cookies are sent, read and the logged in user is given back by the clientManipulator.
When I access my website with "localhost:xy/app_dev.php/account", I always get back an anonymous user and the cookies are not sent. Can someone explain this to me please - and will this have affects in production mode too ? (e.g. a user can also connect with the IP of the website - and then this would bring me to the same problem, wouldn't it ? )
此问题与 this one 有关。 (Symfony 2.7)
我已经实现了 Gos Websocket Bundle,现在可以将消息实时发送到用户可以订阅的频道。当前的问题是,我无法访问我的通知主题 class 中当前登录的用户。我已经尝试了在我链接到的相关 post 中订阅的所有内容。
目前,我正在将“@security.token_storage”注入到我的主题中——但正如我所说,其他方法的行为也相同。我认为这是一个 "cookie / domain" 问题,cookie 没有发送到 websocket 服务器。这是我的配置:
Symfony / php 网络服务器: "Server running on http://127.0.0.1:8000"
Gos websocketconfig.yml:
gos_web_socket:
server:
port: 8081 #The port the socket server will listen on
host: 127.0.0.1 #The host ip to bind to
router:
resources:
- @MessageBundle/Resources/config/pubsub/routing.yml
client:
firewall: main
session_handler: @session.handler.pdo
pushers:
zmq:
host: 127.0.0.1
port: 5555
persistent: true
protocol: tcp
@session.handler.pdo 在 services.yml:
pdo:
class: PDO
arguments:
dsn: mysql:host=%database_host%;port=%database_port%;dbname=%database_name%
user: %database_user%
password: %database_password%
calls:
- [ setAttribute, [3, 2] ] # \PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION
session.handler.pdo:
class: Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler
arguments: [@pdo, {lock_mode: 0}]
配置为使用 pdo 处理程序的框架会话:
session:
# handler_id set to null will use default session handler from php.ini
handler_id: session.handler.pdo
JavaScript 连接客户端与 websocket 的部分:
var webSocket = WS.connect("ws://127.0.0.1:8000");
webSocket.on("socket/connect", function(session){
session.subscribe("account/notification", function(uri, payload){
console.log("Received message", payload.msg);
});
});
这是我的配置,令牌存储被注入到通知主题的服务中。主题的 "onSubscribe" 方法被命中,但用户保持匿名,即使我已登录:
public function onSubscribe(ConnectionInterface $connection, Topic $topic, WampRequest $request)
{
// always returns anonym
dump($this->tokenStorage->getToken()->getUser());die;
}
我错过了什么?
此致。
为了在 web 应用程序和 websocket 之间共享会话,两者必须 运行 在同一域和同一端口上,否则浏览器将不会发送 cookie
Web app: http://www.exemple.com:80
Websocket: ws://ws.exemple.com:80
并且必须为域 exemple.com(没有任何子域)配置 cookie
当您的网络服务器 运行 在端口 8000
上时,您的配置似乎是针对 websocket 的端口 8081 设置的希望对您有所帮助
现在很清楚了,解释在于 HTTP cookie 限制。在此处查找更多详细信息:http://www.cookiecentral.com/faq/#4.3
"The main limit on retrieving a cookie is that you can only retrieve cookies that are valid for the document your script resides in. That is, a script on www.myserver.com cannot read cookies from www.yourserver.com."
此外,我建议您确保 运行 将您的 websocket 服务器连接到 "localhost" 域,以便使用 "localhost" 访问您的网站。这样做,两个域仍然是一致的。
作为我自己的一个问题,我从未检查过通过其地址 (127.0.0.1) 访问该网站并在 "localhost" 上设置 websocket 服务器 运行 是否会触发相同的问题。无论如何,回答你,不,只要你有正确的域(不是 ip),这不应该在产品中重现一次。
但是,Thomas 的回答是不正确的,你不能 运行 两个服务器都在同一个端口上,因为它是端口的定义(一个端口,一个 service/process):https://en.wikipedia.org/wiki/Port_%28computer_networking%29.