gpt4 book ai didi

php - Symfony2 FOSUserBundle 不使用 UserManager 提供缓存的用户实体

转载 作者:IT王子 更新时间:2023-10-29 06:10:03 26 4
gpt4 key购买 nike

我目前正尝试在 Symfony2 中建立一个(希望快)网站。我正在使用 FOSUserBundle 轻松管理用户。我编写了一个自定义 CacheManager 来将实体存储在 Redis 中并取回由 Doctrine 管理的有效实体。我的自定义 UserManager 使用此服务来更快地提供用户数据。一切都很好,但实际上 UserManager 似乎被忽略了。每个请求都会产生一个数据库查询。

我对 FOSUserBundle 的配置(抱歉,必须将项目名称替换为“XXX”):

fos_user:
db_driver: orm
firewall_name: main
user_class: XXX\MainBundle\Entity\User
registration:
form:
type: XXX_user_registration
validation_groups: [XXXRegistration]
confirmation:
enabled: true
template: XXXMainBundle:E-Mail:registration.email.html.twig
from_email:
address: registrierung@XXX.XXX
sender_name: XXX Registrierung
profile:
form:
type: XXX_user_profile
validation_groups: [XXXProfile]
resetting:
email:
template: XXXMainBundle:E-Mail:resetting.email.html.twig
from_email:
address: reset@XXX.XXX
sender_name: XXX.XXX
service:
mailer: fos_user.mailer.twig_swift
user_manager: XXX_main_bundle.security.user_manager

我的服务配置:

    XXX_main_bundle.security.user_manager:
class: XXX\Bundle\MainBundle\Security\UserManager
arguments: [@XXX_main_bundle.cache_manager, @fos_user.entity_manager, @fos_user.util.canonicalizer.default, @security.password_encoder]

我的安全配置:

security:
providers:
fos_userbundle:
id: fos_user.user_provider.username_email

encoders:
FOS\UserBundle\Model\UserInterface: sha512

role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: ROLE_ADMIN
ROLE_DEVELOPER: ROLE_SUPER_ADMIN

firewalls:
main:
pattern: .*
form_login:
provider: fos_userbundle
check_path: /login_check
login_path: /login
logout:
path: /logout
anonymous: true
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/login$
security: false

access_control:
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/, role: ROLE_ADMIN }

我无法向您展示我的 UserManager 和 CacheManager,但如果手动调用和使用它们,它们工作正常!我还尝试编写一个依赖于 UserManager 的自定义 UserProvider。但这总是导致错误:

ServiceNotFoundException in CheckExceptionOnInvalidReferenceBehaviorPass.php line 59: The service "security.authentication.manager" has a dependency on a non-existent service "security.user.provider.concrete.fos_userbundle".

如果我同时启用两个 UserProvider,错误就会消失,但 UserManager 仍然会被忽略。它似乎在我使用 FOSUserBundle 的内置命令时使用,但在 Symfony2 从当前 session 加载用户时不使用。

对不起。因为我的英语不好,也许是愚蠢的问题,但我愿意接受任何批评。

谢谢,贾斯特斯·克莱因

编辑 1:似乎我的 UserManager 没有被完全忽略。它从缓存中返回用户,但 Symfony2 仍然触发数据库查询以获取用户。

编辑 2:发现 FOSUserBundle 的 UserProvider 的刷新功能从数据库加载用户本身,而不是通过 UserManager(wtf?)。因此,重写 UserProvider 似乎提供了线索。但是如果我替换它,我仍然会收到以下错误:

ServiceNotFoundException in CheckExceptionOnInvalidReferenceBehaviorPass.php line 59: The service "security.authentication.manager" has a dependency on a non-existent service "security.user.provider.concrete.fos_userbundle".

编辑 3:我可以通过为 UserProvider 提供与 FOS Bundle 中相同的 key 来覆盖它:

security:
providers:
fos_userbundle:
id: xxx_main_bundle.security.user_provider

这不是最佳实践 ^^ 并非一切正常。我认为这是存储用户的最佳和最快的方式。

最佳答案

最好的解决方案是启用 Doctrine ORM 2.5 中可用的二级缓存功能,它执行的正是:它在 Redis 中缓存实体(或您配置的任何其他缓存)以更快地检索它们。

这在 FOSUserBundle 通过用户名加载用户时没有多大帮助(因为 ORM 在其 SLC 中使用 id 作为标识符,而不是用户名),但这仅在提交登录表单或阅读 remember-me 时发生cookie 如果您使用此功能。但是,它适用于 refresh,其中用户是通过主键加载的(以及项目中需要通过主键加载用户的所有其他地方)。 Doctrine 还将在用户更新时负责更新缓存,以便您获得有效数据(尽管如此,请确保您不要在不使用 ORM 的情况下编辑用户)。

如果你想通过用户名优化用户的加载,你可以编写自己的 UserProvider,它可以在 Redis 中保持用户名和主键之间的映射,然后通过主键向 Doctrine 询问用户对象(它将读取它然后从 ORM 缓存中获取),同时像在 FOSUserBundle 自己的提供者中所做的那样保持主要的刷新(出于安全原因这样做)。该服务然后可以使用 UserManager 或 Doctrine 直接通过用户名加载用户,以防它尚未在您的用户名到 ID 缓存中。
这里不再需要覆盖 UserManager,因为它不再用于身份验证的关键路径。

关于php - Symfony2 FOSUserBundle 不使用 UserManager 提供缓存的用户实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27608342/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com