我有一个应用程序,包括一个运行React的前端服务器和一个运行PHP / Symfony的后端服务器。前端的一部分是使用twig模板(主要用于更新内容的后台表单)开发的,由同一个后端服务器处理,部分使用React开发并驻留在独立的前端服务器中(公共部分)用户访问,具有更多功能)。
系统有三个用户角色:superadmin(通过针对Symfony中配置的内存用户的表单进行身份验证),后台员工(通过与数据库中的User实体相同的表单进行身份验证)和"公共用户"使用应用程序的公共端进行身份验证,通过第三方服务进行身份验证,最终要求我们使用类似于此的代码在我们的API中启动会话:
$token = new UsernamePasswordToken($publicUserEntity, null, 'main', $publicUserEntity->getRoles());
$this->get('security.token_storage')->setToken($token);
$this->get('session')->set('_security_main', serialize($token));
用户通过三种方式成功通过身份验证,但只有当我在后端服务器时才会打开会话,而不是从前端服务器发出请求。
例如,在我使用公共用户登录后,如果我发出请求:
http://backendserverhost/api/someentity/me
该API加载当前会话的用户ID以获取用户的数据,并根据经过身份验证的用户获得正确的响应。
但是如果我从前端服务器(到相同的API和相同的端点)发出相同的请求以获取相同的信息并显示它,它会返回一个错误,好像它是一个匿名用户。
我应该做些什么改变才能"使用"后端服务器中打开的会话使前端服务器请求?
答案 0 :(得分:1)
您可以为用户生成令牌,并在每次请求时将其作为参数传递。
使用FOSOAuthRestBundle,您可以在用户模型类中定义Accesstoken,并使用它在每个请求中进行身份验证。
他们在这里有一个非常好的教程:https://github.com/FriendsOfSymfony/FOSOAuthServerBundle/blob/master/Resources/doc/index.md
答案 1 :(得分:0)
根据所有建议,我最终找到了两种不同的解决方案:
基于Cookie的身份验证(我现在正在使用的身份验证):我在控制器中启动会话,如上所示,并获取会话ID。我将它发送到查询中的React前端服务器,并在他们的请求中将其用作“PHPSESSID”Cookie以进行身份验证。
//Assign session to user
$token = new UsernamePasswordToken($userEntity, null, 'main', $userEntity->getRoles());
$this->get('security.token_storage')->setToken($token);
$this->get('session')->set('_security_main', serialize($token));
//Redirect to homepage
$redirectUrl = $this->container->getParameter('zafter_login_redirect_url');
$response = new RedirectResponse($redirectUrl . '?login=' . $this->get('session')->getId());
$cookie = new Cookie('PHPSESSID', $this->get('session')->getId());
$response->headers->setCookie($cookie);
return $response;
这被证明是解决问题的最快捷,最简单的方法,因为它只需要很少的编码,没有新的依赖或捆绑,我只需要修改登录API中的响应。
基于令牌的身份验证(我可能最终会使用它,因为它对移动客户端也很有用):使用实现JWT身份验证的捆绑包(例如LexikJWTAuthenticationBundle)我生成一个登录后的身份验证令牌,在请求中发送它,客户端(React或Mobile)使用它在subsecuent请求中进行身份验证。
该过程在包的文档中详细说明:https://github.com/lexik/LexikJWTAuthenticationBundle