这是一个Symfony 3.4应用程序,具有网站前端和访问同一后端的移动应用程序。用户可以通过
登录以前,只有一种登录方式(用户名和密码)。身份验证和防火墙配置有效。添加社交网络身份验证需要更改防火墙配置,现在防护身份验证已部分中断。
到目前为止,我有信心的是,我们需要为Web用户(主要)和移动应用程序用户(API)使用单独的防火墙。对Web用户进行一次身份验证,然后将已登录的用户信息存储在会话cookie中,但对移动应用程序用户进行身份验证时会收到每个传入请求。当移动用户成功登录后,他们将获得jwt令牌作为响应,并将随每个后续请求一起发送。
似乎最大的问题是其余的防火墙配置。在当前配置中,“主”防火墙按预期工作。但是,针对移动用户的“ api”防火墙的某些问题已损坏。登录使用相同的防护验证器,以便它们按预期返回jwt令牌。但是,与令牌一起发送的后续请求都将导致403访问被拒绝响应。我怀疑词汇认证器永远不会从请求中获取jwt令牌,因此用户似乎从未登录过。
身份验证器已经过测试,对于网络用户和移动用户而言,它们似乎都可以正常工作。 lexik jwt身份验证器的配置也正确-或自移动用户仍然只有一个身份验证器以来就没有更改。这意味着键,密码短语,令牌ttl。
一个可行的想法是为移动登录URL和其余的移动路由设置单独的防火墙,因为它们由不同的身份验证器处理。我在没有任何改善的情况下进行了尝试:登录可以正常工作,但jwt身份验证没有。以下是security.yml的相关部分:
security:
...
providers:
db_users:
entity: { ... }
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js|api)/(password/reset)
security: false
api:
pattern: ^/api/
stateless: true
lexik_jwt: ~
anonymous: false
guard:
provider: db_users
authenticators:
- main.form_login_authenticator
- main.google_login_authenticator
- main.fb_login_authenticator
- lexik_jwt_authentication.jwt_token_authenticator
entry_point: main.form_login_authenticator
main:
pattern: ^/
guard:
provider: db_users
authenticators:
- main.form_login_authenticator
- main.google_login_authenticator
- main.fb_login_authenticator
entry_point: main.form_login_authenticator
form_login:
remember_me: true
login_path: login
check_path: login
always_use_default_target_path: true
default_target_path: /redirect
target_path_parameter: _target_path
use_referer: false
require_previous_session: false
anonymous: true
...
这里发生了什么事?我应该如何调试此问题? (除了使用邮递员模拟来自移动应用程序的json请求)
其他信息:所有三个自定义身份验证器都创建一个jwt令牌,例如:
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
{
// mobile users:
if ( $request->getRequestFormat() == 'json') {
return new JsonResponse(['token' => $this->jwtManager->create($token->getUser())]);
// web users handled here
}
然后关于访问模式(或如何处理请求以及由哪个身份验证器进行处理),这是main.form_login_authenticator
的示例
public function supports(Request $request)
{
return ('login' === $request->attributes->get('_route') || 'api_login_check' === $request->attributes->get('_route'))
&& $request->isMethod('POST');
}
不过,身份验证器似乎可以正常工作。登录作品。无法使用jwt令牌保持登录状态。
答案 0 :(得分:1)
终于可以了。该解决方案的主要思想是分离防火墙:一个用于移动登录路由,另一个用于其余的移动(api)路由。这是有效的配置,省略了三个点的标记。 main
防火墙已按照问题所示进行配置。
security:
...
firewalls:
...
api_login:
pattern: ^/api/(login|google-login|fb-login)
stateless: true
anonymous: true
guard:
provider: db_users
authenticators:
- main.form_login_authenticator
- main.google_login_authenticator
- main.fb_login_authenticator
entry_point: main.form_login_authenticator
api:
pattern: ^/api
stateless: true
guard:
provider: db_users
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
main:
...
身份验证器服务名称的前缀最初来自防火墙main
的名称,这不再有意义,因为它们现在已在多个防火墙之间共享。
答案 1 :(得分:0)
首先,对于api防火墙,您应该仅具有jwt身份验证器,因为即使auth也是如此。完成社交网络后,您必须生成自己的jwt令牌。
第二,您可以将您的访问模式发送给我们吗?这可以为我们提供更多线索。
第三,我不确定api防火墙的入口点是否应与形式一(https://symfony.com/doc/current/components/security/firewall.html#entrypoint)相同