手动创建 symfony2 记住我 cookie (FOSUserBundle)
有人可以解释一下如何在控制器中手动创建记住我的 cookie 吗?
我希望用户在按下“注册”后保持登录状态 按钮,之后无需使用其凭据登录。
我尝试过手动创建 cookie,但我猜测 cookie 值不正确,因此“记住我”功能 不起作用。 设置具有正确名称的 cookie。我已经查过了。
使用正常模式时,“记住我”功能可以按预期工作 使用用户凭据的登录过程。
安全.yml security.yml 记住我
security:
firewalls:
main:
remember_me:
lifetime: 86400
domain: ~
path: /
key: myKey
这就是我现在所拥有的,即使设置了cookie,它也不起作用。
$um = $this->get('fos_user.user_manager');
$member = $um->createUser();
… Form stuff with bindRequest etc.
$um->updatePassword($member);
$um->updateUser($member);
$providerKey = $this->container->getParameter('fos_user.firewall_name');
$securityKey = 'myKey';
$token = new RememberMeToken($member, $providerKey, $securityKey,
$member->getRoles());
$this->container->get('security.context')->setToken($token);
$redirectResponse = new RedirectResponse($url);
$redirectResponse->headers->setCookie(
new \Symfony\Component\HttpFoundation\Cookie(
'REMEMBERME',
base64_encode(implode(':', array($member->getUsername(),
$member->getPassword()))),
time() + 60*60*24
)
);
return $redirectResponse;
更新:
我也尝试过与 PersistentTokenBasedRememberMeServices 类具有反射,但它不起作用。设置了 cookie 但它不起作用
$token = $this->container->get('security.context')->getToken();
$providerKey = $this->container->getParameter('fos_user.firewall_name');
$securityKey = 'myKey';
$persistenService = new
PersistentTokenBasedRememberMeServices(array($um), $providerKey,
$securityKey, array('path' => '/', 'name' => 'REMEMBERME', 'domain' =>
null, 'secure' => false, 'httponly' => true,
'lifetime' => 86400));
$persistenService->setTokenProvider(new InMemoryTokenProvider());
$method = new \ReflectionMethod('Symfony\Component\Security\Http\RememberMe\PersistentTokenBasedRememberMeServices',
'onLoginSuccess');
$method->setAccessible(true);
$method->invoke($persistenService, $request, $redirectResponse, $token);
我正在使用 Symfony v2.0.5 和 FOSUserBundle 1.0
更新 2:
我尝试了第三种方法。与上面相同但没有反射:
$token = $this->container->get('security.context')->getToken();
$providerKey = $this->container->getParameter('fos_user.firewall_name');
$securityKey = 'myKey';
$persistenService = new PersistentTokenBasedRememberMeServices(array($um), $providerKey, $securityKey, array('path' => '/', 'name' => 'REMEMBERME', 'domain' => null, 'secure' => false, 'httponly' => true, 'lifetime' => 31536000, 'always_remember_me' => true, 'remember_me_parameter' => '_remember_me'));
$persistenService->setTokenProvider(new InMemoryTokenProvider());
$persistenService->loginSuccess($request, $redirectResponse, $token);
Could somebody explain how you can manually create a remember me cookie in a controller?
I want the users to stay logged in after they pressed the "register"
button, without having to login with their credentials afterwards.
I've tried to create a cookie manually but i'm guessing the cookie
value is incorrect, and therefor the "remember me" functionality
doesn't work.
A cookie with the correct name gets set. I've checked that.
The remember me functionality works as expected when using the normal
login procedure with the user's credentials.
security.yml
security.yml remember me
security:
firewalls:
main:
remember_me:
lifetime: 86400
domain: ~
path: /
key: myKey
This is what I have now, even though the cookie is set, it doesn't work.
$um = $this->get('fos_user.user_manager');
$member = $um->createUser();
… Form stuff with bindRequest etc.
$um->updatePassword($member);
$um->updateUser($member);
$providerKey = $this->container->getParameter('fos_user.firewall_name');
$securityKey = 'myKey';
$token = new RememberMeToken($member, $providerKey, $securityKey,
$member->getRoles());
$this->container->get('security.context')->setToken($token);
$redirectResponse = new RedirectResponse($url);
$redirectResponse->headers->setCookie(
new \Symfony\Component\HttpFoundation\Cookie(
'REMEMBERME',
base64_encode(implode(':', array($member->getUsername(),
$member->getPassword()))),
time() + 60*60*24
)
);
return $redirectResponse;
Update:
I've also tried working with the
PersistentTokenBasedRememberMeServices class with reflection but it does not work. a cookie gets set but it's not working
$token = $this->container->get('security.context')->getToken();
$providerKey = $this->container->getParameter('fos_user.firewall_name');
$securityKey = 'myKey';
$persistenService = new
PersistentTokenBasedRememberMeServices(array($um), $providerKey,
$securityKey, array('path' => '/', 'name' => 'REMEMBERME', 'domain' =>
null, 'secure' => false, 'httponly' => true,
'lifetime' => 86400));
$persistenService->setTokenProvider(new InMemoryTokenProvider());
$method = new \ReflectionMethod('Symfony\Component\Security\Http\RememberMe\PersistentTokenBasedRememberMeServices',
'onLoginSuccess');
$method->setAccessible(true);
$method->invoke($persistenService, $request, $redirectResponse, $token);
I'm using Symfony v2.0.5 and FOSUserBundle 1.0
UPDATE 2:
I've tried a 3rd way. The same as above but without reflection:
$token = $this->container->get('security.context')->getToken();
$providerKey = $this->container->getParameter('fos_user.firewall_name');
$securityKey = 'myKey';
$persistenService = new PersistentTokenBasedRememberMeServices(array($um), $providerKey, $securityKey, array('path' => '/', 'name' => 'REMEMBERME', 'domain' => null, 'secure' => false, 'httponly' => true, 'lifetime' => 31536000, 'always_remember_me' => true, 'remember_me_parameter' => '_remember_me'));
$persistenService->setTokenProvider(new InMemoryTokenProvider());
$persistenService->loginSuccess($request, $redirectResponse, $token);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我是这样做的。我没有使用 FOSUserBundle,而是使用 Doctrine Entity User Provider,但根据您的需求进行调整应该很简单。这是一个通用的解决方案:
只要记住你必须将
always_remember_me option
设置为true
(就像我在上面的代码中所做的那样)或者以某种方式将其放在 $_POST 参数中,否则AbstractRememberMeServices
的方法isRememberMeRequested
将返回 false,并且不会存储 cookie。不过,您已经非常接近正确的解决方案了:)您做错了(在第三次尝试中)是您更改了此处参数的顺序:
看看
__construct()
in >AbstractRememberMeServices.php。您应该将$securityKey
作为第二个参数传递,将$providerKey
作为第三个参数传递,而不是像您错误地那样传递相反的方式;)我还不知道,是如何直接在控制器中从 security.yml 获取参数而不是重复它。通过使用 $this->container->getParameter() 我可以获取存储在 config.yml 中
parameters
键下的参数,但不能获取配置中较高位置的参数树。对此有什么想法吗?Here is how I did it. I'm not using the FOSUserBundle and I'm using Doctrine Entity User Provider, but it should be trivial to adjust to your needs. Here is a general solution:
Just remember you have to set
always_remember_me option
totrue
(like I did in the code above) or have it in your $_POST parameters somehow, otherwise methodisRememberMeRequested
ofAbstractRememberMeServices
will return false and the cookie won't be stored.You were pretty close to the correct solution though :) What you did wrong (in the 3rd attempt) is that you've changed the order of parameters here:
Take a look at
__construct()
inAbstractRememberMeServices.php
. You should pass a$securityKey
as 2nd argument and$providerKey
as 3rd argument, not the other way around like you did by mistake ;)What I don't know yet, is how to get parameters from security.yml directly in the controller not to duplicate it. By using
$this->container->getParameter()
I can get parameters stored underparameters
key in config.yml, but not the ones places higher in the configuration tree. Any thoughts on this?如果您直接设置 Rememberme Cookie,则必须使用以下格式:
哈希值的位置:
密钥是您在
remember_me
部分。这是取自 Symfony/Component/Security/Http/RememberMe/TokenBasedRememberMeService.php 文件中的
processAutoLoginCookie()
方法。这都是由同一个类中的
generateCookieValue()
方法完成的。不过,我不建议直接使用这种方式,而是尝试看看是否可以调用 TokenBasedRememberMeService::onLoginSuccess() 方法,该方法会为您设置此 cookie,以使代码更加健壮和便携式。
If you are setting the rememberme cookie directly, you have to use the following format:
where the hash will be:
the key is the key you have entered in your security(.xml/.yml) in the
remember_me
section.This is taken from
processAutoLoginCookie()
method in the Symfony/Component/Security/Http/RememberMe/TokenBasedRememberMeService.php file.This is all done by the
generateCookieValue()
method in the same class.However, I would not recommend on using doing it this way directly, but try to see if you can call the
TokenBasedRememberMeService::onLoginSuccess()
method, which sets this cookie for you to make the code more robust and portable.对我来说,最简单的解决方案是扩展 BaseTokenBasedRememberMeServices 并让它
在控制器中进行处理;
然后响应将 cookie 设置为 $remember_me_cookie
我希望它对你有用 2.
For me the easiest solution was extend a BaseTokenBasedRememberMeServices and let it handle
and in controller;
then response set cookie to $remember_me_cookie
I hope its works with you 2.
当我尝试使用 守卫身份验证。
在这种情况下,我没有 Response 对象能够使用 $response->headers->setCookie() 并且需要使用 setcookie().
而在这种情况下,创建 RedirectResponse 是不合适的。
这需要重构,但我发布了我的服务所基于的原始程序
I had the same issue when I tried to set REMEMBERME cookie an User after a connection by token, using Guard Authentication.
In this situation I had no Response object to be able to use $response->headers->setCookie() and needs to use setcookie().
And in this situation, create a RedirectResponse is not appropriate.
This needs to be refactored but I post the raw procedural on which I based my service