提问人:Oscar Manuel Gómez Senovilla 提问时间:9/4/2023 最后编辑:Oscar Manuel Gómez Senovilla 更新时间:9/7/2023 访问量:49
MIs在 symfony 5+ 中使用 prod 环境中的自定义查询时的功能
MIsfunction in symfony 5+ when using custom query in prod environment
问:
我正在开发一个使用 user@domain 进行登录的应用程序,一个实体用于域,另一个实体用于链接到域的用户。这个应用程序是开源的,因此您可以从 https://github.com/omgslinux/vmail/ 自由克隆。所有测试都在 debian 下进行。
我从symfony 3.x开始,这些功能在开发和部署到生产环境时仍然有效。然后,在升级到 5.x 和 6.x 时,将更改使用自定义查询进行登录的升级方式。我为新的登录系统进行了必要的更改,并且在开发中一切正常,但是我发现在部署到 prod 时,有一个 100% 可重现的奇怪行为,但我无法知道为什么会发生这种情况。
问题是,如果我使用域中 id == 0 的任何用户登录,一切正常,但如果域 id 为 != 0,我会被重定向到登录屏幕,就像登录错误一样,但没有错误消息。如果那时我手动输入我应该被重定向的 url,我会被重定向回登录。我已经在主页中转储了 $this->getUser(),并使用相同的凭据,而在 dev 中返回一个用户实体,在 prod 中返回 null。如果我在存储库中转储查询,则在转到主页之前,查询将返回预期的记录。
如果我强制输入错误的密码,我可以在屏幕上看到登录错误。
我已经用 apache 和 nginx 测试了这一点,将APP_ENV变量设置为“prod”。如果我将APP_ENV设置为“dev”,则一切正常,包括底部的调试栏。
我只在另外两台服务器中复制了生产部分,并得到了完全相同的结果。
重现结果:默认的 git 分支是 symfony 3.x,所以你必须克隆 symfony62 分支才能进行最新的更改。安装后,创建一个新域,然后创建该新域中的用户,并尝试使用此新用户登录。
下面是 security.yaml:
security:
password_hashers:
App\Entity\User:
id: App\Utils\PassEncoder
providers:
app_vmail_users:
entity:
class: App\Entity\User
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
lazy: true
provider: app_vmail_users
#logout_on_user_change: true
form_login:
login_path: login
check_path: login
username_parameter: _username
password_parameter: _password
logout:
path: logout
target: /
access_control:
- { path: ^/login, roles: ['PUBLIC_ACCESS'] }
- { path: ^/admin, roles: ['ROLE_ADMIN'] }
- { path: ^/manage, roles: ['ROLE_MANAGER'] }
- { path: ^/user, roles: ['ROLE_USER'] }
role_hierarchy:
ROLE_ADMIN: [ROLE_MANAGER, ROLE_USER]
ROLE_MANAGER: [ROLE_USER]
以及用户存储库类中的 loader 函数:
public function loadUserByIdentifier(string $username): ?UserInterface
{
$a=explode('@', $username);
if (count($a) != 2) {
return null;
}
$user=$a[0];
$domain=$a[1];
return $this->createQueryBuilder('u')
->leftJoin('u.domain', 'd')
->where('u.name = :user AND d.name = :domain')
->setParameter('user', $user)
->setParameter('domain', $domain)
->getQuery()
->getOneOrNullResult();
}
任何帮助都是值得赞赏的。提前致谢。
答:
我找到了一种让它工作的方法。通过保留 monolog 默认值,我在 prod () 中根本没有调试:config/monolog.yaml
when@prod:
monolog:
handlers:
main:
type: fingers_crossed
action_level: error
handler: nested
excluded_http_codes: [404, 405]
buffer_size: 50 # How many messages should be saved? Prevent memory leaks
nested:
type: stream
path: php://stderr
level: debug
formatter: monolog.formatter.json
console:
type: console
process_psr_3_messages: false
channels: ["!event", "!doctrine"]
deprecation:
type: stream
channels: [deprecation]
path: php://stderr
由于在 dev 中我可以调试应用程序,因此我将“main”部分替换为相应的“dev”部分:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
channels: ["!event"]
在不删除缓存的情况下,我发现我开始在路径指示的 prod 中拥有日志,并且由于应用程序没有更改并且它正在“工作”,因此我没有做任何其他事情。然后,我想到了删除 prod 缓存,允许自动重新生成。做完这个之后...一切正常!!
我通过恢复 monolog 更改并完全删除 prod 缓存来重现这一点。结果是“旧”故障又回来了,所以我撤消了最新的更改,删除了缓存,然后从一开始就恢复了应有的工作。
所以,我想知道:当使用自定义查询登录时,prod 的默认 monolog 默认值是否始终有效?这可能是一个错误吗?我把这个问题留给开发人员或其他任何人来检查一下。
评论