【发布时间】:2020-11-05 23:23:03
【问题描述】:
使用 docker 在我的本地完美运行应用程序。
当我部署它时,我不明白为什么每次请求都会启动一个新会话。似乎不能来自代码,因为它完全一样。
会话存储在 redis 数据库中(如果我使用文件系统会话,我也会遇到同样的错误)。在那里我可以看到创建的所有新会话。 (见最后一个代码块)。
从日志中我可以清楚地识别出$request->getSession()->getId() 在每个请求上都发生了变化,但 PHPSESSID cookie 没有变化。
例如:
第一个请求
[2020-11-02 15:03:59] request.INFO: Matched route "app_login". {"route":"app_login","route_parameters":{"_route":"app_login","_controller":"App\\Controller\\SecurityController::login"},"request_uri":"https://foo.bar.dev/login","method":"POST"} []
[2020-11-02 15:03:59] security.DEBUG: Checking for guard authentication credentials. {"firewall_key":"main","authenticators":1} []
[2020-11-02 15:03:59] security.DEBUG: Checking support on guard authenticator. {"firewall_key":"main","authenticator":"App\\Security\\LoginFormAuthenticator"} []
[2020-11-02 15:03:59] app.DEBUG: [LoginFormAuthenticator::supports] $request session id => 6491ddf4e8f3e2eaa22b44b3a98c094a [] []
[2020-11-02 15:03:59] app.DEBUG: [LoginFormAuthenticator::supports] $_COOKIE => {"PHPSESSID":"87cf6185b652f8d713c45031ebe6d8a4"} []
第二个
[2020-11-02 15:04:33] request.INFO: Matched route "app_login". {"route":"app_login","route_parameters":{"_route":"app_login","_controller":"App\\Controller\\SecurityController::login"},"request_uri":"https://foo.bar.dev/login","method":"POST"} []
[2020-11-02 15:04:33] security.DEBUG: Checking for guard authentication credentials. {"firewall_key":"main","authenticators":1} []
[2020-11-02 15:04:33] security.DEBUG: Checking support on guard authenticator. {"firewall_key":"main","authenticator":"App\\Security\\LoginFormAuthenticator"} []
[2020-11-02 15:04:33] app.DEBUG: [LoginFormAuthenticator::supports] $request session id => 41b08dac8a803337a48dca7d5b33b840 [] []
[2020-11-02 15:04:33] app.DEBUG: [LoginFormAuthenticator::supports] $_COOKIE => {"PHPSESSID":"87cf6185b652f8d713c45031ebe6d8a4"} []
KUBERNETES
ingress-nginx.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: secured-front
namespace: foo-apis-dev
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/rewrite-target: /$1
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/affinity: "cookie"
nginx.ingress.kubernetes.io/affinity-mode: "persistent"
nginx.ingress.kubernetes.io/session-cookie-name: "PHPSESSID"
nginx.ingress.kubernetes.io/session-cookie-path: "/"
nginx.ingress.kubernetes.io/session-cookie-samesite: "Lax"
nginx.ingress.kubernetes.io/session-cookie-expires: "172800000"
nginx.ingress.kubernetes.io/session-cookie-max-age: "172800000"
spec:
tls:
- hosts:
- bar.foo.dev
secretName: tls-secret
rules:
- host: bar.foo.dev
http:
paths:
- backend:
serviceName: bar-nginx
servicePort: 80
path: /(.*)
Symfony APP
security.yaml
[...]
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: lazy
pattern: ^/.*
logout:
path: app_logout
target: login
guard:
authenticators:
- App\Security\LoginFormAuthenticator
[...]
services.yaml
[...]
Redis:
class: Redis
calls:
- connect:
- '%env(REDIS_HOST)%'
- '%env(int:REDIS_PORT)%'
Symfony\Component\HttpFoundation\Session\Storage\Handler\RedisSessionHandler:
arguments:
- '@Redis'
- { prefix: 'admin_phpsess_' }
[...]
packages.framework.yaml
[...]
session:
handler_id: Symfony\Component\HttpFoundation\Session\Storage\Handler\RedisSessionHandler
cookie_secure: auto
cookie_samesite: lax
[...]
REDIS
127.0.0.1:6379> KEYS *admin*
1) "admin_phpsess_245e4a79fe35e2320943770061884c24"
2) "admin_phpsess_0ff29464322b3c2cfc5d8f5fd323ef75"
3) "admin_phpsess_26812c17f93a5d28a71853b77ac85386"
4) "admin_phpsess_7fbae6f0b1fdbe9576e41c9eee2cd60f"
版本:
- PHP 7.4.12
- Symfony 4.4
- Kubernetes 1.17.9
- redis (pecl) 5.3.2
重要提示
问题在于 redis 配置。
我采取了使用PdoSessionHandler 的步骤,它有效。问题来自 Redis 和/或 Kubernetes,我已经尝试了 2 个小时来指出产生此错误但目前不可能的配置。
【问题讨论】:
-
在您的情况下,容器参数
framework.session.name和 PHP INI 配置指令session.name的值是多少?如果framework.session.name未定义,Symfony 会退回到php.ini中的session.name指令。/login是否在您的防火墙配置中定义为“匿名”路由。security.yml? -
如果我转储一个 phpinfo 我得到 =>
session.name PHPSESSID -
查看我的更新答案。
-
嗨@BastienSander - 你有没有想过这个?
标签: php symfony session kubernetes