{"id":1592,"date":"2015-10-12T12:58:23","date_gmt":"2015-10-12T12:58:23","guid":{"rendered":"https:\/\/intelligentbee.com\/blog\/?p=1592"},"modified":"2024-10-25T09:18:54","modified_gmt":"2024-10-25T09:18:54","slug":"how-to-create-a-custom-symfony2-password-encoder","status":"publish","type":"post","link":"https:\/\/intelligentbee.com\/blog\/how-to-create-a-custom-symfony2-password-encoder\/","title":{"rendered":"How to Create a Custom Symfony2 Password Encoder"},"content":{"rendered":"<p>As you advance through your Symfony2 developer life, you will probably encounter the need to create a custom Symfony2 password encoder for you project. One of the most common reasons to do this, is when you migrate from an old project (different technology) and you have to keep users together with their working passwords. As you probably cannot find out the plain passwords to be able to just save them to your new database, you will need to replicate the algorithm used to encode them so they will keep working when the transition is over.<\/p>\n<h2>How to Create a Custom Symfony2 Password Encoder<\/h2>\n<p>In order to add a new, custom, password encoder to your Symfony2 project, you will need to create the encoder class, register it as a service and then specify it in the security.yml configuration file of your project.<\/p>\n<p>Below you will find the necessary code\u00a0to implement this:<\/p>\n<p>&nbsp;<\/p>\n<p><code>AppBundle\/Security\/Core\/Encoder\/MyPasswordEncoder.php<\/code><\/p>\n<pre class=\"lang:php decode:true \">&lt;?php\r\n\r\nnamespace AppBundle\\Security\\Core\\Encoder;\r\n\r\nuse Symfony\\Component\\Security\\Core\\Encoder\\BasePasswordEncoder;\r\nuse Symfony\\Component\\Security\\Core\\Exception\\BadCredentialsException;\r\n\r\nclass MyPasswordEncoder extends BasePasswordEncoder\r\n{\r\n    private $ignorePasswordCase;\r\n\r\n    \/**\r\n     * Constructor.\r\n     *\r\n     * @param bool $ignorePasswordCase Compare password case-insensitive\r\n     *\/\r\n    public function __construct($ignorePasswordCase = false)\r\n    {\r\n        $this-&gt;ignorePasswordCase = $ignorePasswordCase;\r\n    }\r\n\r\n    \/**\r\n     * {@inheritdoc}\r\n     *\/\r\n    public function encodePassword($raw, $salt)\r\n    {\r\n        if ($this-&gt;isPasswordTooLong($raw)) {\r\n            throw new BadCredentialsException('Invalid password.');\r\n        }\r\n\r\n        return sha1($this-&gt;mergePasswordAndSalt($raw, $salt));\r\n    }\r\n\r\n    \/**\r\n     * {@inheritdoc}\r\n     *\/\r\n    public function isPasswordValid($encoded, $raw, $salt)\r\n    {\r\n        if ($this-&gt;isPasswordTooLong($raw)) {\r\n            return false;\r\n        }\r\n\r\n        try {\r\n            $pass2 = $this-&gt;encodePassword($raw, $salt);\r\n        } catch (BadCredentialsException $e) {\r\n            return false;\r\n        }\r\n\r\n        if (!$this-&gt;ignorePasswordCase) {\r\n            return $this-&gt;comparePasswords($encoded, $pass2);\r\n        }\r\n\r\n        return $this-&gt;comparePasswords(strtolower($encoded), strtolower($pass2));\r\n    }\r\n    \r\n    \/**\r\n     * Merges a password and a salt.\r\n     *\r\n     * @param string $password the password to be used\r\n     * @param string $salt     the salt to be used\r\n     *\r\n     * @return string a merged password and salt\r\n     *\r\n     * @throws \\InvalidArgumentException\r\n     *\/\r\n    protected function mergePasswordAndSalt($password, $salt)\r\n    {\r\n        if (empty($salt)) {\r\n            return $password;\r\n        }\r\n\r\n        return $salt.$password;\r\n    }\r\n}\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p><code>app\/config\/services.yml<\/code><\/p>\n<pre class=\"lang:yaml decode:true\">services:\r\n    app.my_password_encoder:\r\n        class: AppBundle\\Security\\Core\\Encoder\\MyPasswordEncoder<\/pre>\n<p>&nbsp;<\/p>\n<p><code>app\/config\/security.yml<\/code><\/p>\n<pre class=\"lang:yaml decode:true \">security:\r\n    encoders:\r\n        FOS\\UserBundle\\Model\\UserInterface:\r\n            id: app.my_password_encoder<\/pre>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>As you advance through your Symfony2 developer life, you will probably encounter the need to create a custom Symfony2 password [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":1597,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[82],"tags":[128,191,194,217,235],"yst_prominent_words":[310,319,426,594,798,985],"post_mailing_queue_ids":[],"_links":{"self":[{"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/posts\/1592"}],"collection":[{"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/comments?post=1592"}],"version-history":[{"count":4,"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/posts\/1592\/revisions"}],"predecessor-version":[{"id":133283,"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/posts\/1592\/revisions\/133283"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/media\/1597"}],"wp:attachment":[{"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/media?parent=1592"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/categories?post=1592"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/tags?post=1592"},{"taxonomy":"yst_prominent_words","embeddable":true,"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/yst_prominent_words?post=1592"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}