9

コントローラでremembermeCookieを手動で作成する方法を誰かが説明できますか?

ユーザーが「登録」ボタンを押した後も、後で資格情報を使用してログインしなくても、ログインしたままにしておく必要があります。

手動でCookieを作成しようとしましたが、Cookieの値が正しくないと推測しているため、「rememberme」機能が機能しません。正しい名前のCookieが設定されます。私はそれをチェックしました。

ユーザーの資格情報を使用して通常のログイン手順を使用すると、rememberme機能は期待どおりに機能します。

security.ymlsecurity.yml覚えておいてください

security:
   firewalls:
       main:
           remember_me:
               lifetime: 86400
               domain:   ~
               path:     /
               key:      myKey

これは私が今持っているものです、クッキーが設定されていても、それは機能しません。

$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クラスを操作しようとしましたが、機能しません。クッキーが設定されますが、機能していません

$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:

私は3番目の方法を試しました。上記と同じですが、反射はありません。

$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);
4

4 に答える 4

14

これが私がやった方法です。私は FOSUserBundle を使用しておらず、Doctrine Entity User Provider を使用していますが、ニーズに合わせるのは簡単です。一般的な解決策は次のとおりです。

// 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;

(上記のコードで行ったように) に設定するか、何らかの方法で $_POST パラメーターに設定always_remember_me optionする必要があることを覚えておいてください。そうしないと、メソッドはfalse を返し、Cookie は保存されません。trueisRememberMeRequestedAbstractRememberMeServices

しかし、あなたは正しい解決策にかなり近づいていました:)あなたが間違っていたのは(3回目の試行で)、ここでパラメーターの順序を変更したことです:

$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'));

__construct()をご覧くださいAbstractRememberMeServices.php$securityKeyaを第 2 引数および第 3 引数として渡す必要があり$providerKeyます。誤って行ったように、その逆ではありません ;)

私がまだ知らないのは、 security.yml からパラメーターをコントローラーで直接取得して複製しないようにする方法です。を使用すると、config.yml のキーの$this->container->getParameter()下に格納されたパラメーターを取得できますが、構成ツリーの上位にあるパラメーターは取得できません。parametersこれについて何か考えはありますか?

于 2012-01-30T20:13:02.273 に答える
10

rememberme cookie を直接設定する場合は、次の形式を使用する必要があります。

base64_encode(<classname>:base64_encode(<username>):<expiry-timestamp>:<hash>)

ハッシュは次のようになります。

sha256(<classname> . <username> . <expiry-timestamp> . <password> . <key>)

キーは、セクションのセキュリティ (.xml/.yml) に入力したキーですremember_me

これはprocessAutoLoginCookie()、ファイル内のメソッドから取得されSymfony/Component/Security/Http/RememberMe/TokenBasedRememberMeService.phpます。

これはすべてgenerateCookieValue()、同じクラスのメソッドによって行われます。

ただし、この方法を直接使用することはお勧めしませんがTokenBasedRememberMeService::onLoginSuccess()、コードをより堅牢で移植性の高いものにするために、この Cookie を設定するメソッドを呼び出すことができるかどうかを確認してください。

于 2012-01-30T18:48:43.140 に答える