Symfony2创建自己的编码器来存储密码

gui*_*ier 13 php security hash symfony

我是Symfony2的新手,我可能有一个关于在我的数据库中编码用户密码的简单问题.

我想以这种方式编码并在DB中存储我的用户密码:

encoded_password = salt . sha1 ( salt . raw_password )
Run Code Online (Sandbox Code Playgroud)

我发现了各种编码器(sha1,sha512,明文),我在我的数据库raw_password {salt}中看到了明文,但我仍然不满意Symfony2中的signin/login/getSalt()方法.

如果你可以给我一个提升(请假设我不想使用现有的用户管理包,我想自己制作)这将是真棒!

谢谢

编辑:

我可以在我的signinAction()中做到这一点:

$salt = substr(md5(time()),0,10);
$pwd = $encoder->encodePassword($user->getPassword(), $salt);
$user->setPassword($salt.$pwd);
Run Code Online (Sandbox Code Playgroud)

我可以在我的getSalt()中做到这一点:

return substr($this->password,0,10);
Run Code Online (Sandbox Code Playgroud)

但我目前只有我的loginAction():(见这里:http://symfony.com/doc/current/book/security.html )

// src/Acme/SecurityBundle/Controller/Main;
namespace Acme\SecurityBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Security\Core\SecurityContext;

class SecurityController extends Controller
{
    public function loginAction()
    {
        $request = $this->getRequest();
        $session = $request->getSession();

        // get the login error if there is one
        if ($request->attributes->has(SecurityContext::AUTHENTICATION_ERROR)) {
            $error = $request->attributes->get(SecurityContext::AUTHENTICATION_ERROR);
        } else {
            $error = $session->get(SecurityContext::AUTHENTICATION_ERROR);
        }

        return $this->render('AcmeSecurityBundle:Security:login.html.twig', array(
            // last username entered by the user
            'last_username' => $session->get(SecurityContext::LAST_USERNAME),
            'error'         => $error,
        ));
    }
}
Run Code Online (Sandbox Code Playgroud)

如何告诉Symfony2在登录操作期间按照我需要的方式检查密码?(执行编码(密码,盐)而不是salt.encode(密码,盐)

gre*_*emo 48

为简单起见:您必须创建并添加一个新服务,将其添加到您的包中以及User该类将使用它的规格.首先,您必须实现自己的密码编码器:

namespace Acme\TestBundle\Service;

use Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface;

class Sha256Salted implements PasswordEncoderInterface
{

    public function encodePassword($raw, $salt)
    {
        return hash('sha256', $salt . $raw); // Custom function for password encrypt
    }

    public function isPasswordValid($encoded, $raw, $salt)
    {
        return $encoded === $this->encodePassword($raw, $salt);
    }

}
Run Code Online (Sandbox Code Playgroud)

然后,您将添加服务定义,并希望指定为该类使用自定义编码器User.在TestBundle/Resources/config/services.yml中添加自定义编码器:

services:
    sha256salted_encoder:
        class: Acme\TestBundle\Service\Sha256Salted
Run Code Online (Sandbox Code Playgroud)

因此,在app/config/security.yml中,您可以将自定义类指定为默认编码器(对于Acme\TestBundle\Entity\User类):

 encoders:
   Acme\TestBundle\Entity\User:
     id: acme.test.sha256salted_encoder
Run Code Online (Sandbox Code Playgroud)

当然,盐在密码加密中起着核心作用.Salt是唯一的,并为每个用户存储.该类User可以使用YAML注释自动生成(表当然应包含字段username,password,salt等)并且应该实现UserInterface.

最后,当您必须创建一个新的时,您可以使用它(控制器代码)Acme\TestBundle\Entity\User:

// Add a new User
$user = new User();
$user->setUsername = 'username';
$user->setSalt(uniqid(mt_rand())); // Unique salt for user

// Set encrypted password
$encoder = $this->container->get('acme.test.sha256salted_encoder')
  ->getEncoder($user);
$password = $encoder->encodePassword('MyPass', $user->getSalt());
$user->setPassword($password);
Run Code Online (Sandbox Code Playgroud)

  • 完善!!你让我今天一整天都感觉很好!在我的旧解决方案和使用sf2的新解决方案之间迁移期间,我绝望地丢失了所有密码;) (2认同)