2012-01-22 33 views
8

क्या कोई यह समझा सकता है कि आप मैन्युअल रूप से मुझे नियंत्रक में कुकी कैसे याद कर सकते हैं?एक सिम्फनी 2 बनाएं मुझे कुकी को मैन्युअल रूप से याद रखें (FOSUserBundle)

मैं उन में लॉग इन रहने के बाद वे "पंजी" बटन दबाया, बाद में उनके पत्र के साथ प्रवेश किए बिना चाहते हैं।

मैंने मैन्युअल रूप से कुकी बनाने की कोशिश की है, लेकिन मुझे लगता है कि कुकी मान गलत है, और "मुझे याद रखें" कार्यक्षमता काम नहीं करता है। सही नाम वाली एक कुकी सेट हो जाती है। मैंने इसे चेक किया है।

मुझे याद रखें कि उपयोगकर्ता की क्रेडेंशियल्स के साथ सामान्य लॉगिन प्रक्रिया का उपयोग करते समय मुझे कार्यक्षमता की अपेक्षा की जाती है।

security.yml मुझे

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

याद security.yml यह वही है मैं अब है, भले ही कुकी सेट है, यह काम नहीं करता।

$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 वर्ग के साथ काम करने की कोशिश की है, लेकिन यह काम नहीं करता। एक कुकी सेट हो जाता है, लेकिन यह मैं Symfony v2.0.5 और FOSUserBundle उपयोग कर रहा हूँ काम नहीं कर रहा

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

1,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); 

उत्तर

10

आप सीधे rememberme कुकी सेट कर रहे हैं, तो आप निम्न स्वरूप का उपयोग करने के लिए है:

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

जहां हैश होगा:

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

कुंजी वह कुंजी है जिसे आपने अपनी सुरक्षा (.xml/.yml) में remember_me अनुभाग में दर्ज किया है।

यह Symfony/घटक/सुरक्षा/HTTP/RememberMe/TokenBasedRememberMeService.php फ़ाइल में processAutoLoginCookie() विधि से लिया जाता है।

यह सब एक ही कक्षा में generateCookieValue() विधि द्वारा किया गया है।

हालांकि, मैं इसे सीधे इस तरह से करने का सुझाव नहीं दूंगा, लेकिन यह देखने का प्रयास करें कि क्या आप TokenBasedRememberMeService::onLoginSuccess() विधि को कॉल कर सकते हैं, जो कोड को और अधिक मजबूत और पोर्टेबल बनाने के लिए आपके लिए यह कुकी सेट करता है।

12

यहां बताया गया है कि मैंने यह कैसे किया। मैं FOSUserBundle का उपयोग नहीं कर रहा हूं और मैं सिद्धांत इकाई उपयोगकर्ता प्रदाता का उपयोग कर रहा हूं, लेकिन आपकी आवश्यकताओं को समायोजित करने के लिए यह छोटा होना चाहिए।यहाँ एक सामान्य समाधान है:

// 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 को स्थापित करने के लिए (जैसे मैं ऊपर कोड में किया था) या अपने $ _POST मापदंडों किसी भी तरह में पाना है, अन्यथा विधि AbstractRememberMeServices की isRememberMeRequested अवास्तविक लौटाते हैं और कुकी संग्रहित नहीं किया जाएगा।

आप बहुत हालांकि सही समाधान :) तुम गलत क्या किया (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। जैसे आप गलती से किया था आप के चारों ओर एक $securityKey 2 के रूप में तर्क और $providerKey 3 के रूप में तर्क, नहीं दूसरी तरह के पास करना चाहिए;)

मैं अभी तक क्या पता नहीं है, सीधे security.yml से पैरामीटर प्राप्त करने के लिए है नियंत्रक इसे डुप्लिकेट नहीं करना है। $this->container->getParameter() का उपयोग करके मैं config.yml में parameters कुंजी के तहत संग्रहीत पैरामीटर प्राप्त कर सकता हूं, लेकिन कॉन्फ़िगरेशन पेड़ में उच्च स्थान नहीं है। इस पर कोई विचार?

+1

आधारित security.yml में कुकी पैरामीटर हो रही के लिए और डुप्लिकेट से बचने के पोस्ट, तो आप उन्हें parameters.yml में और सुरक्षा में रखना चाहिए .yml उन्हें% your_parameter_name% के साथ कॉल करें। वे अब सुरक्षा में उपलब्ध हैं और पैरामीटर – guillaumepotier

+3

+1 इसके लिए सिम्फनी 2 सुरक्षा कक्षाओं का उपयोग करने के लिए उपलब्ध हैं। ध्यान रखें कि याद रखने वाली कुकीज़ के लिए डिफ़ॉल्ट कुकी नाम 'REMEMBERME' है। केवल तभी जब आप उसी कुकी नाम का उपयोग फ़ायरवॉल के रूप में करते हैं, तो आप अपने मैन्युअल सेट कुकी के विरुद्ध प्रमाणीकरण कर रहे हैं सुरक्षा श्रोता द्वारा पहचाना जाएगा। – flu

+1

तर्क 1 सिम्फनी \ ब्रिज \ डॉक्टरेट \ सुरक्षा \ उपयोगकर्ता \ EntityUserProvider :: __ निर्माण() को इंटरफ़ेस को कार्यान्वित करना चाहिए सिद्धांत \ सामान्य \ दृढ़ता \ प्रबंधक रजिस्ट्री, सिद्धांत \ ORM \ EntityManager का उदाहरण मुझे दिया गया है कि मुझे यह मिला है: –

0

मेरे लिए सबसे आसान समाधान एक BaseTokenBasedRememberMeServices का विस्तार करने और इसे संभाल

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()); 

तो प्रतिक्रिया कुकी $ remember_me_cookie

को मैं तुम्हें 2.

0

के साथ अपने काम करता है आशा है कि मैं एक ही मुद्दा था जब मैं टोकन से एक कनेक्शन के बाद REMEMBERME कुकी सेट करने के लिए एक उपयोगकर्ता की कोशिश की निर्धारित करते हैं, Guard Authentication का उपयोग कर।

इस स्थिति में मुझे $ प्रतिक्रिया-> शीर्षलेख-> setCookie() का उपयोग करने में सक्षम होने के लिए कोई प्रतिक्रिया वस्तु नहीं थी और setcookie() का उपयोग करने की आवश्यकता है। और इस स्थिति में, एक RedirectResponse बनाएँ उचित नहीं है।

यह पुनर्संशोधित होने की जरूरत है, लेकिन मैं कच्चे प्रक्रियात्मक है जिस पर मैं अपने सेवा

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