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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7878887/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 03:33:04  来源:igfitidea点击:

Symfony2 create own encoder for storing password

phpsecuritysymfonyhash

提问by guillaumepotier

I'm new to Symfony2 and I have maybe a simple question about encoding my user passwords in my DB.

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

I'd like to encode and store in DB my users' password that way:

我想以这种方式对我的用户密码进行编码并存储在数据库中:

encoded_password = salt . sha1 ( salt . raw_password )

I've found various encoders (sha1, sha512, plaintext), I saw that with plaintext I have in my DB raw_password{salt} but I'm still not comfortable with signin/login/getSalt() method in Symfony2.

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

If you could give me a lift on that (please, assume I do not want to use an existing bundle for UserManagement, I'd like to make my own) it would be AWESOME!

如果你能给我一个提升(请假设我不想使用现有的 UserManagement 包,我想自己制作)那就太棒了!

Thanks

谢谢

EDIT:

编辑:

I could do that in my signinAction():

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

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

I could do that in my getSalt():

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

return substr($this->password,0,10);

But I currently have only that in my loginAction(): (see here: http://symfony.com/doc/current/book/security.html)

但我目前在我的 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,
        ));
    }
}

How can I tell Symfony2 to check the password during the login action the way I need? (curently doing encode(password,salt) and not salt.encode(password,salt)

我如何告诉 Symfony2 在登录操作期间按照我需要的方式检查密码?(目前正在做 encode(password,salt) 而不是 salt.encode(password,salt)

回答by gremo

To make it simple: you have to create and add a new Service, add it to your bundle and specity that the Userclass will use it. First you have to implement your own password encoder:

简单起见:您必须创建并添加一个新的Service,将其添加到您的包中,并指定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);
    }

}

Then you'll add the service definitionand you want to specify to use your custom encoderfor the class User. In TestBundle/Resources/config/services.ymlyou add custom encoder:

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

services:
    sha256salted_encoder:
        class: Acme\TestBundle\Service\Sha256Salted

and in app/config/security.ymlyou can therefore specify your custom class as default encoder (for Acme\TestBundle\Entity\Userclass):

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

 encoders:
   Acme\TestBundle\Entity\User:
     id: acme.test.sha256salted_encoder

Of course, salt plays a central role in password encryption. Salt is unique and is stored for each user. The class Usercan be auto-generated using YAML annotations (table should - of course - contain fields username, password, salt and so on) and should implement UserInterface.

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

Finally you can use it (controller code) when you have to create a new Acme\TestBundle\Entity\User:

最后,当您必须创建一个新的时,您可以使用它(控制器代码)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);

回答by sami boussacsou

Thank you gremo, There's a small problem in the last snippet of your code, when using the service we should put it's name "sha256salted_encoder" and not acme.test.sha256salted_encoder. in addition

谢谢gremo,你的代码的最后一个片段有一个小问题,在使用服务时,我们应该把它的名字命名为“sha256salted_encoder”而不是acme.test.sha256salted_encoder。此外

// 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('security.encoder_factory')
  ->getEncoder($user);
$password = $encoder->encodePassword('MyPass', $user->getSalt());
$user->setPassword($password);

first of all we will call the security encoder, then we will find

首先我们会调用安全编码器,然后我们会发现

sha256salted_encoder

sha256salted_encoder

and the service will be useful.

该服务将很有用。

All the best

祝一切顺利

回答by Beno?t

Basically, you should / must only use the bcrypt encoder to safely store password into your database.

基本上,您应该/必须只使用 bcrypt 编码器将密码安全地存储到您的数据库中。

here is why:

原因如下:

http://dustwell.com/how-to-handle-passwords-bcrypt.html

http://dustwell.com/how-to-handle-passwords-bcrypt.html

http://adambard.com/blog/3-wrong-ways-to-store-a-password/

http://adambard.com/blog/3-wrong-ways-to-store-a-password/

To configure this encoder you should edit your security.yml file

要配置此编码器,您应该编辑您的 security.yml 文件

security:
    encoders:
        Symfony\Component\Security\Core\User\UserInterface: bcrypt

This encoder is used inside the UserPasswordEncoderclass which can be found here: Symfony\Component\Security\Core\Encoder

此编码器在UserPasswordEncoder类中使用,可在此处找到:Symfony\Component\Security\Core\Encoder