手动创建symfony2记住我cookie(FOSUserBundle)
有人能解释一下如何在控制器中手动创建“记住我”cookie吗 我希望用户在按下“注册表”后保持登录状态 按钮,而无需随后使用其凭据登录 我试图手动创建cookie,但我猜是cookie 值不正确,因此“记住我”功能 不起作用。 将设置具有正确名称的cookie。我查过了 当使用普通模式时,“记住我”功能按预期工作 使用用户凭据的登录过程 security.yml 我记得我手动创建symfony2记住我cookie(FOSUserBundle),symfony,remember-me,fosuserbundle,Symfony,Remember Me,Fosuserbundle,有人能解释一下如何在控制器中手动创建“记住我”cookie吗 我希望用户在按下“注册表”后保持登录状态 按钮,而无需随后使用其凭据登录 我试图手动创建cookie,但我猜是cookie 值不正确,因此“记住我”功能 不起作用。 将设置具有正确名称的cookie。我查过了 当使用普通模式时,“记住我”功能按预期工作 使用用户凭据的登录过程 security.yml 我记得我 security: firewalls: main: remember_me:
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;
更新:
我也试着和
PersistentTokenBasedMemberMeservices类具有反射,但它不起作用。一块饼干被设置好了,但它不起作用
$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);
我使用的是symfonyv2.0.5和fosuserbundle1.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);
如果直接设置Memberme cookie,则必须使用以下格式:
base64_encode(<classname>:base64_encode(<username>):<expiry-timestamp>:<hash>)
base64\u编码(:base64\u encode():)
其中散列将是:
sha256(<classname> . <username> . <expiry-timestamp> . <password> . <key>)
sha256(…)
密钥是您在记住我
部分的安全(.xml/.yml)中输入的密钥
这取自Symfony/Component/Security/Http/RememberMe/TokenBasedRememberMeService.php文件中的processAutologyCookie()
方法
这都是通过同一类中的generateCookieValue()
方法完成的
但是,我不建议直接使用这种方法,但请尝试调用
TokenBasedMemberMeservice::onLoginSAccess()
方法,该方法为您设置此cookie,以使代码更加健壮和可移植。我是这样做的。我没有使用FOSUserBundle,我使用的是Doctrine实体用户提供者,但根据您的需要进行调整应该是微不足道的。以下是一个通用解决方案:
// after registration and persisting the user object to DB, I'm logging the user in automatically
$token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
// but you can also get the token directly, if you're user is already logged in
$token = $this->container->get('security.context')->getToken();
// write cookie for persistent session storing
$providerKey = 'main'; // defined in security.yml
$securityKey = 'MySecret'; // defined in security.yml
$userProvider = new EntityUserProvider($this->getDoctrine()->getEntityManager(), 'MyCompany\MyBundle\Entity\User', 'username');
$rememberMeService = new TokenBasedRememberMeServices(array($userProvider), $securityKey, $providerKey, array(
'path' => '/',
'name' => 'MyRememberMeCookie',
'domain' => null,
'secure' => false,
'httponly' => true,
'lifetime' => 1209600, // 14 days
'always_remember_me' => true,
'remember_me_parameter' => '_remember_me')
);
$response = new Response();
$rememberMeService->loginSuccess($request, $response, $token);
// further modify the response
// ........
return $response;
请记住,您必须将始终记住我选项
设置为true
(就像我在上面的代码中所做的那样),或者以某种方式将其设置在$\u POST参数中,否则AbstractMemberServices
的方法IsRememberRequested
将返回false,并且cookie将不会被存储
不过,您已经非常接近正确的解决方案:)您(在第三次尝试中)的错误在于更改了此处参数的顺序:
$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'));
查看AbstractMemberServices.php
中的\uu construct()
。您应该将$securityKey
作为第二个参数传递,将$providerKey
作为第三个参数传递,而不是错误地传递;)
我还不知道的是,如何在控制器中直接从security.yml获取参数,以避免重复。通过使用
$this->container->getParameter()
我可以获取存储在config.yml中参数
键下的参数,但不能获取配置树中较高位置的参数。对此有何想法?对我来说,最简单的解决方案是扩展BaseTokedRememberMeservices并让它处理
namespace AppBundke\Security\Http;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\Security\Http\RememberMe\TokenBasedRememberMeServices as BaseTokenBasedRememberMeServices;
class TokenBasedRememberMeServices extends BaseTokenBasedRememberMeServices
{
protected $options_new = array('name' => 'REMEMBERME', 'domain' => null, 'path' => '/');
public function __construct($userProvider, $secret, $providerKey, array $options = array(), LoggerInterface $logger = null)
{
return parent::__construct(array($userProvider), $secret, $providerKey, array_merge($this->options_new, $options));
}
public function generateCookie($user, $username, $expires, $password)
{
$cookie = new Cookie(
$this->options['name'],
parent::generateCookieValue(get_class($user), $username, $expires, $password),
$expires,
$this->options['path'],
$this->options['domain'],
$this->options['secure'],
$this->options['httponly']
);
return $cookie;
}
}
以及在控制器中
$user = $this->getUser();
$providerKey = $this->getParameter('fos_user.firewall_name');
$secret = $this->getParameter('secret');
$cookie_life_time = $this->getParameter('cookie_life_time');
$remember_me_service = new TokenBasedRememberMeServices($user, $secret, $providerKey );
$remember_me_cookie = $remember_me_service->generateCookie($user, $user->getUsername(),(time() + $cookie_life_time), $user->getPassword());
然后,响应将cookie设置为$membere\u me\u cookie
我希望它能与您一起工作。2.当我尝试在通过令牌连接后使用设置REMEMBERME cookie给用户时,我遇到了相同的问题 在这种情况下,我没有响应对象可以使用$Response->headers->setCookie(),需要使用()。 在这种情况下,创建重定向响应是不合适的 这需要重构,但我发布了我基于服务的原始过程
$expires = time() + 2628000;
$hash = hash_hmac(
'sha256',
get_class($user).$user->getUsername().$expires.$user->getPassword(), 'secret in parameters.yml'
);
$value = base64_encode(implode(':', [get_class($user), base64_encode($user->getUsername()), $expires, $hash]));
setcookie(
'REMEMBERME',
$value,
$expires,
'/',
'host',
'ssl boolean',
true
);
为了在security.yml中获取cookie参数并避免重复,您应该将它们放在parameters.yml和security.yml中,并使用%your_parameter_name%调用它们。它们现在可以在security和parameters+1中使用,以便为此使用Symfony2安全类。请记住,“记住我”cookies的默认cookie名称是
REMEMBERME
。仅当您使用与防火墙相同的cookie名称时,安全侦听器才会识别针对手动设置cookie进行身份验证的防火墙。传递给Symfony\Bridge\doctor\security\User\EntityUserProvider的参数1::\uu construct()必须实现接口doctor\Common\Persistence\manager注册表,Doctrine\ORM\EntityManager的实例,我只发送了Doctrine而没有EntityManager,修复了D:问题。所以基本上只需$this->getDoctrine(),谢谢:)现在我需要确保它工作正常。