Kubernetes上的Symfony-每次请求都会启动新会话

cgyqldqp  于 2023-05-28  发布在  Kubernetes
关注(0)|答案(2)|浏览(181)

让一个应用程序在我的本地与docker完美运行。
当我部署它时,我不知道为什么每个请求都启动一个新的会话。它似乎不能来自代码,因为它是完全相同的。
会话存储在redis DB上(如果我使用文件系统会话,我也有同样的错误)。在那里,我可以看到创建的所有新会话。(参见最后一个代码块)。
从日志中,我可以清楚地识别出$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"} []

库伯内特酒店
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
安全.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
[...]

服务.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个小时来指出产生此错误的配置,但现在不可能。

o4tp2gmn

o4tp2gmn1#

请尝试使用Predis会话处理程序。
1.设置您的服务

# services.yaml
    Redis:
        class: \Predis\Client
        arguments:
            - 'redis://%env(REDIS_HOST)%:%env(REDIS_PORT)%'

    predis_session_handler:
        class: 'Predis\Session\Handler'
        arguments:
            - '@Redis'

1.配置Symfony

# framework.yaml
framework:
  session:
    handler_id: predis_session_handler
hrysbysz

hrysbysz2#

nginx.ingress.kubernetes.io/session-cookie-path: "/"设置为,而不是/(.*)正则表达式。
Symfony的framework.session.cookie_path的默认参数也是/。(文件)
进一步将nginx.ingress.kubernetes.io/session-cookie-name更改为"INGRESSCOOKIE"或省略注解。
nginx入口的会话cookie用于确定初始请求被路由到哪个pod,并将任何进一步的请求路由到完全相同的pod。
它是一个不同于PHP会话的会话cookie,因此应该有一个不同的cookie名称。入口会话cookie已经创建,并且可能会用您的配置覆盖php会话cookie。
如果你使用的是redis会话,就不需要将连续的请求路由到集群中的同一个pod。

相关问题