Symfony 3-如何通过bcrypt加密的密码对用户进行身份验证?

时间:2019-04-03 08:12:31

标签: php symfony encryption bcrypt

我在数据库中有一个User实体,通过bcrypt进行了密码加密。

实际上,创建用户时,我会生成7个字符的随机密码,然后通过邮件发送给他。该密码使用bcrypt加密,然后在数据库的password属性中进行加密。

我希望当用户从我的登录表单连接时,他可以输入我通过电子邮件发送给他的密码以进行身份​​验证。但是我不知道该怎么做。我可以看不同的站点,看不到。

此外,我认为我的代码有些混乱……我的最终目标是对用户进行身份验证,因此他具有打开的会话,可以断开连接,并且仅限于某些页面。而且还可以管理用户是否被激活及其有效期。

我强调我是symfony的初学者(我是在实习的两个星期前发现它的,而且我对PHP的了解很少,所以对我来说很难)

我不使用fosUserBundle捆绑包。

这是我的代码:

User.php:

<?php

namespace Site\PagesBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Security\Core\User\UserInterface;


/**
 * User
 *
 * @ORM\Table(name="user")
 * @ORM\Entity(repositoryClass="Site\PagesBundle\Repository\UserRepository")
 */
class User implements UserInterface, \Serializable
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="username", type="string", length=255, nullable=true, unique=true)
     */
    private $username;


    /**
     * @var string
     *
     * @ORM\Column(name="nom", type="string", length=255)
     */
    private $nom;

       /**
     * @var string
     *
     * @ORM\Column(name="prenom", type="string", length=255)
     */
    private $prenom;



    /**
     * @var string
     *
     * @ORM\Column(name="email", type="string", length=254, unique=true)
     */
    private $email;

     /**
     * @Assert\Length(max=4096)
     */
    private $plainPassword;

    /**
     * @var string
     *
     * @ORM\Column(name="password", type="string", length=64, nullable=true)
     */
    private $password;

    /**
     * @var int
     *
     * @ORM\Column(name="nbTelechargementsAuto", type="integer", nullable=true)
     */
    private $nbTelechargementsAuto;

    /**
     * @var bool
     *
     * @ORM\Column(name="isActif", type="boolean")
     */
    private $isActif=0;

    /**
     * @ORM\Column(type="datetime", nullable=true)
     *
     * @var \DateTime
    */
    private $createdAt;


    /**
     * @var bool
     *
     * @ORM\Column(name="isCreated", type="boolean")
     */
    private $isCreated=0;

    /**
     * @ORM\Column(type="array")
     */
    private $roles;

    /**
     * Set createdAt
     *
     * @param \DateTime $createdAt
     *
     * @return User
     */
    public function setCreatedAt()
    {
        $this->createdAt = new \DateTimeImmutable();

        return $this;
    }

    /**
     * Get createdAt
     *
     * @return \DateTime
     */
    public function getCreatedAt()
    {
        return $this->createdAt;
    }


    /**
     * Get id
     *
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set nom
     *
     * @param string $nom
     *
     * @return User
     */
    public function setNom($nom)
    {
        $this->nom = $nom;

        return $this;
    }

    /**
     * Get nom
     *
     * @return string
     */
    public function getNom()
    {
        return $this->nom;
    }

        /**
     * Set nom
     *
     * @param string $username
     *
     * @return User
     */
    public function setUsername($username)
    {
        $this->username = $username;

        return $this;
    }

    /**
     * Get nom
     *
     * @return string
     */
    public function getUsername()
    {
        return $this->username;
    }

    /**
     * Set prenom
     *
     * @param string $prenom
     *
     * @return User
     */
    public function setPrenom($prenom)
    {
        $this->prenom = $prenom;

        return $this;
    }

    /**
     * Get prenom
     *
     * @return string
     */
    public function getPrenom()
    {
        return $this->prenom;
    }

    /**
     * Set email
     *
     * @param string $email
     *
     * @return User
     */
    public function setEmail($email)
    {
        $this->email = $email;

        return $this;
    }

    /**
     * Get email
     *
     * @return string
     */
    public function getEmail()
    {
        return $this->email;
    }

    /**
     * Set password
     *
     * @param string $password
     *
     * @return User
     */
    public function setPassword($password)
    {
        $this->password = $password;

        return $this;
    }

    /**
     * Get password
     *
     * @return string
     */
    public function getPassword()
    {
        return $this->password;
    }

    /**
     * Set nbTelechargementsAuto
     *
     * @param integer $nbTelechargementsAuto
     *
     * @return User
     */
    public function setNbTelechargementsAuto($nbTelechargementsAuto)
    {
        $this->nbTelechargementsAuto = $nbTelechargementsAuto;

        return $this;
    }

    /**
     * Get nbTelechargementsAuto
     *
     * @return int
     */
    public function getNbTelechargementsAuto()
    {
        return $this->nbTelechargementsAuto;
    }

    /**
     * Set isActif
     *
     * @param boolean $isActif
     *
     * @return User
     */
    public function setIsActif($isActif)
    {
        $this->isActif = $isActif;

        return $this;
    }

    /**
     * Get isActif
     *
     * @return bool
     */
    public function getIsActif()
    {
        return $this->isActif;
    }


        /**
     * Set isCreated
     *
     * @param boolean $isCreated
     *
     * @return User
     */
    public function setIsCreated($isCreated)
    {
        $this->isCreated = $isCreated;

        return $this;
    }

    /**
     * Get isCreated
     *
     * @return bool
     */
    public function getIsCreated()
    {
        return $this->isCreated;
    }

    public function __construct()
    {
        $this->roles = ['ROLE_USER'];
    }

    public function getPlainPassword()
    {
        return $this->plainPassword;
    }

    public function setPlainPassword($password)
    {
        $this->plainPassword = $password;
    }

    public function getSalt()
    {
        // you *may* need a real salt depending on your encoder
        // see section on salt below
        return null;
    }

    public function getRoles()
    {
        return $this->roles;
    }

    public function eraseCredentials()
    {
    }

    /** @see \Serializable::serialize() */
    public function serialize()
    {
        return serialize([
            $this->id,
            $this->username,
            $this->password,
            $this->email,
            $this->nbTelechargementsAuto,
            $this->nom,
            $this->prenom,
            // see section on salt below
            // $this->salt,
        ]);
    }

    /** @see \Serializable::unserialize() */
    public function unserialize($serialized)
    {
        list (
            $this->id,
            $this->username,
            $this->password,
            $this->email,
            $this->nbTelechargementsAuto,
            $this->nom,
            $this->prenom,
            // see section on salt below
            // $this->salt
        ) = unserialize($serialized, ['allowed_classes' => false]);
    }


    /**
     * Activation du compte
     */
    public function activerCompte($nbPackages, $nbHomonymes)
    {

        if($this->getIsCreated() == 0)
        {
            $unUsername = $this->getNom();
            $unUsername .= ".";
            $unUsername .= $this->getPrenom();
            $unUsername = strtolower($unUsername);

            if($nbHomonymes > 0)
            {
                $nbHomonymes++;
                $unUsername .= $nbHomonymes;
            }


            $this->setUsername(strtolower($unUsername));
            $this->setNbTelechargementsAuto($nbPackages);
            $this->setCreatedAt();
            $this->setIsCreated(true);

        }

        $password = $this->generatePassword();

        $this->setPlainPassword($password);
        $this->setIsActif(true);

        return $this;
    }

    public function constructionUsername()
    {
        $unUsername = $this->getNom();
        $unUsername .= ".";
        $unUsername .=$this->getPrenom();

        return $unUsername;
    }

    /**
     * Désactivation du compte
     */
    public function desactiverCompte()
    {
        $this->setIsActif(false);
        $this->setCreatedAt();

        return $this;
    }

    public function registration()
    {
        // Passage Nom 1ère lettre Majuscule le reste minuscule
        $leNom = $this->getNom();
        $leNom = strtolower($leNom);
        $leNom = ucfirst($leNom);

        // Passage Nom 1ère lettre Majuscule le reste minuscule
        $lePrenom = $this->getPrenom();
        $lePrenom = strtolower($lePrenom);
        $lePrenom = ucfirst($lePrenom);

        $this->setNom($leNom);
        $this->setPrenom($lePrenom);
        $this->setCreatedAt();
    }

    /**
     * Génération d'un mot de passe
     * $nb_caractere = nombre de caractère du mdp
     * Pas de caractère qui se ressemble (L minuscule, 1 et i majuscule, Zéro et la lettre o.)
     * Sécurité supplémentaire avec : caractères speciaux: - + = $ % ! @ #
     * Pas d'espace pour éviter les erreurs
     */
    function generatePassword($nb_caractere = 7)
{
        $mot_de_passe = "";

        $chaine = "abcdefghjkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ023456789@!$?&";
        $longeur_chaine = strlen($chaine);

        for($i = 1; $i <= $nb_caractere; $i++)
        {
            $place_aleatoire = mt_rand(0,($longeur_chaine-1));
            $mot_de_passe .= $chaine[$place_aleatoire];
        }

        return $mot_de_passe;   
}


}

config.php:

imports:
    - { resource: parameters.yml }
    - { resource: security.yml }
    - { resource: services.yml }

# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters:
    locale: en

framework:
    # ...
    templating:
        engines: ['twig']
    #esi: ~
    #translator: { fallbacks: ['%locale%'] }
    secret: '%secret%'
    router:
        resource: '%kernel.project_dir%/app/config/routing.yml'
        strict_requirements: ~
    form: ~
    csrf_protection: ~
    validation: { enable_annotations: true }
    #serializer: { enable_annotations: true }
    default_locale: '%locale%'
    trusted_hosts: ~
    session:
        # https://symfony.com/doc/current/reference/configuration/framework.html#handler-id
        handler_id: session.handler.native_file
        save_path: '%kernel.project_dir%/var/sessions/%kernel.environment%'
    fragments: ~
    http_method_override: true
    assets: ~
    php_errors:
        log: true

# Twig Configuration
twig:
    debug: '%kernel.debug%'
    strict_variables: '%kernel.debug%'
    form_themes: ['bootstrap_4_layout.html.twig']


# Doctrine Configuration
doctrine:
    dbal:
        driver: pdo_mysql
        host: '%database_host%'
        port: '%database_port%'
        dbname: '%database_name%'
        user: '%database_user%'
        password: '%database_password%'
        charset: UTF8
        # if using pdo_sqlite as your database driver:
        #   1. add the path in parameters.yml
        #     e.g. database_path: '%kernel.project_dir%/var/data/data.sqlite'
        #   2. Uncomment database_path in parameters.yml.dist
        #   3. Uncomment next line:
        #path: '%database_path%'

    orm:
        auto_generate_proxy_classes: '%kernel.debug%'
        naming_strategy: doctrine.orm.naming_strategy.underscore
        auto_mapping: true

# Swiftmailer Configuration
swiftmailer:
    transport: '%mailer_transport%'
    host: '%mailer_host%'
    username: '%mailer_user%'
    password: '%mailer_password%'
    spool: { type: memory }

sensio_framework_extra:
   router:
        annotations: false

assetic:
    debug:          "%kernel.debug%"
    use_controller: false
    bundles:    [ ]
   #java: /usr/bin/java
    java: C:\Program Files\Java\jdk1.8.0_65\bin\java.exe
    filters:
        cssrewrite: ~
        cssembed:
            jar: "%kernel.root_dir%/Resources/java/cssembed.jar"        
            yui_js:
            jar: "%kernel.root_dir%/Resources/java/yuicompressor.jar"
        yui_css:
            jar: "%kernel.root_dir%/Resources/java/yuicompressor.jar"
        lessphp:
            file: "%kernel.root_dir%/../vendor/oyejorge/less.php/lessc.inc.php"   
            apply_to: ".less$"
    assets:
        jquery_js:
            inputs:
                - "%kernel.root_dir%/../vendor/components/jquery/jquery.min.js"            
            filters: [?yui_js]
            output: js/jquery.min.js

        bootstrap_css:
            inputs:
                - "%kernel.root_dir%/../vendor/twbs/bootstrap/less/bootstrap.less"
            filters:
                - lessphp
                - cssrewrite
            output: css/bootstrap.css            

        bootstrap_js:
            inputs:
                - "%kernel.root_dir%/../vendor/twbs/bootstrap/js/affix.js"
                - "%kernel.root_dir%/../vendor/twbs/bootstrap/js/alert.js"
                - "%kernel.root_dir%/../vendor/twbs/bootstrap/js/button.js"
                - "%kernel.root_dir%/../vendor/twbs/bootstrap/js/carousel.js"
                - "%kernel.root_dir%/../vendor/twbs/bootstrap/js/collapse.js"
                - "%kernel.root_dir%/../vendor/twbs/bootstrap/js/dropdown.js"
                - "%kernel.root_dir%/../vendor/twbs/bootstrap/js/modal.js"
                - "%kernel.root_dir%/../vendor/twbs/bootstrap/js/tooltip.js"
                - "%kernel.root_dir%/../vendor/twbs/bootstrap/js/popover.js"
                - "%kernel.root_dir%/../vendor/twbs/bootstrap/js/scrollspy.js"
                - "%kernel.root_dir%/../vendor/twbs/bootstrap/js/tab.js"
                - "%kernel.root_dir%/../vendor/twbs/bootstrap/js/transition.js"
            filters: [?yui_js]
            output: js/bootstrap.js             
        fonts_glyphicons_eot:
            inputs:
                - "%kernel.root_dir%/../vendor/twbs/bootstrap/fonts/glyphicons-halflings-regular.eot"
            output: "fonts/glyphicons-halflings-regular.eot"
        fonts_glyphicons_svg:
            inputs:
                - "%kernel.root_dir%/../vendor/twbs/bootstrap/fonts/glyphicons-halflings-regular.svg"
            output: "fonts/glyphicons-halflings-regular.svg"
        fonts_glyphicons_ttf:
            inputs:
                - "%kernel.root_dir%/../vendor/twbs/bootstrap/fonts/glyphicons-halflings-regular.ttf"
            output: "fonts/glyphicons-halflings-regular.ttf"
        fonts_glyphicons_woff:
            inputs:
                - "%kernel.root_dir%/../vendor/twbs/bootstrap/fonts/glyphicons-halflings-regular.woff"

            output: "fonts/glyphicons-halflings-regular.woff"

stof_doctrine_extensions: 
    orm: 
        default: 
            sluggable: true

vich_uploader:
    db_driver: orm
    twig: true
    storage: file_system

    mappings:
        paquet:
            uri_prefix: fichiers/packages
            upload_destination: '%kernel.root_dir%/../web/fichiers/packages/' 

            inject_on_load: true
            delete_on_update: true
            delete_on_remove: true

        notice:
            uri_prefix: fichiers/notices
            upload_destination: '%kernel.root_dir%/../web/fichiers/notices/' 

            inject_on_load: false
            delete_on_update: true
            delete_on_remove: true

fos_ck_editor:
    configs:
        my_config:
            toolbar: [ ["Source", "-", "Save"], "/", ["Anchor"], "/", ["Maximize"] ]
            uiColor:                "#000000"

Security.yml:

# To get started with security, check out the documentation:
# https://symfony.com/doc/current/security.html
security:
    encoders:
        Site\PagesBundle\Entity\User: bcrypt

    role_hierarchy:
        ROLE_ADMIN:       ROLE_USER
        ROLE_SUPER_ADMIN: [ ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH ]

    # https://symfony.com/doc/current/security.html#b-configuring-how-users-are-loaded
    providers:
        in_memory: {memory: ~}
        in_database:
            entity:
                class: Site\PagesBundle\Entity\User
                property: username

        our_db_provider:
            entity:
                class: Site\PagesBundle\Entity\User
                property: username
                # if you're using multiple entity managers
                # manager_name: customer

    firewalls:
        # disables authentication for assets and the profiler, adapt it according to your needs
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false

        main:
            anonymous: true

            provider: in_database

            form_login:
                login_path: security_login
                check_path: security_login

            logout:
                path: security_logout
                target: informations

            # activate different ways to authenticate

            # https://symfony.com/doc/current/security.html#a-configuring-how-your-users-will-authenticate
            #http_basic: ~

            # https://symfony.com/doc/current/security/form_login_setup.html
            #form_login: ~

控制器的一部分,我用来管理与用户导航相关的内容,包括其身份验证

DefaultController.php:

<?php

namespace Site\PagesBundle\Controller;

use Site\PagesBundle\Entity\User;
use Site\PagesBundle\Entity\Paquet;
use Site\PagesBundle\Entity\TypeUser;
use Site\PagesBundle\Entity\Information;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Vich\UploaderBundle\Handler\DownloadHandler;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;

/**
 * Default controller.
 *
 * @Route("accueil")
 */
class DefaultController extends Controller
{

    /**
     * Accueil
     *
     * @Route("/", name="connexion_index")
     * @Method({"GET", "POST"})
     */
    public function indexAction(Request $request, UserPasswordEncoderInterface $passwordEncoder)
    {

        $em = $this->getDoctrine()->getManager(); //Récupération du manager

        $listeInfos = $em->getRepository('PagesBundle:Information')->getInformationsZone("Zone 1"); //Récupération d'une liste d'informations

        $user = new User(); //Initialisation de l'objet User
        $form = $this->createForm('Site\PagesBundle\Form\ConnexionType', $user); //Formulaire de création
        $form->handleRequest($request);

        //Traitement si le formulaire est soumis ( Ajout du package dans la BDD )
        if ($form->isSubmitted() && $form->isValid()) {
            $em = $this->getDoctrine()->getManager();
            $em->persist($user);

            $password = $passwordEncoder->encodePassword($user, $user->getPlainPassword());

            $valide = $this->getDoctrine()->getManager()->getRepository('PagesBundle:User')->authentifier($user->getUsername(),$password);
            dump($valide);
            dump($password);

            if($valide == 1)
            {
                return $this->redirectToRoute('accueil');
            }

            else
            {
                return $this->render('@Pages/Default/connexion.html.twig',array(
                    'user' => $user,
                    'form' => $form->createView(),
                    'listeInfos' => $listeInfos,
                ));
            }

            // On ajoute un package, donc on offre un téléchargement supplémentaire aux utilisateurs concernés
            $this->getDoctrine()->getManager()->getRepository('PagesBundle:User')->updateNbDDLAll("inc"); 

            //return $this->redirectToRoute('paquets_index'); // Redirection page de gestion de packages
        }



        return $this->render('@Pages/Default/connexion.html.twig',array(
            'user' => $user,
            'form' => $form->createView(),
            'listeInfos' => $listeInfos,
        ));
    }

感谢您的帮助!

编辑:

我的功能:

 /**
     * Accueil
     *
     * @Route("/", name="connexion_index")
     * @Method({"GET", "POST"})
     */
    public function indexAction(Request $request, UserPasswordEncoderInterface $passwordEncoder)
    {

        $em = $this->getDoctrine()->getManager(); //Récupération du manager

        $listeInfos = $em->getRepository('PagesBundle:Information')->getInformationsZone("Zone 1"); //Récupération d'une liste d'informations

        $user = new User(); //Initialisation de l'objet User
        $form = $this->createForm('Site\PagesBundle\Form\ConnexionType', $user); //Formulaire de création
        $form->handleRequest($request);

        //Traitement si le formulaire est soumis ( Ajout du package dans la BDD )
        if ($form->isSubmitted() && $form->isValid()) {
            $em = $this->getDoctrine()->getManager();
            $em->persist($user);

            $password = $passwordEncoder->encodePassword($user, $user->getPlainPassword());

            $valide = $this->getDoctrine()->getManager()->getRepository('PagesBundle:User')->authentifier($user->getUsername(),$password);
            dump($valide);
            dump($password);

            if($valide == 1)
            {
                return $this->redirectToRoute('accueil');
            }

            else
            {
                return $this->render('@Pages/Default/connexion.html.twig',array(
                    'user' => $user,
                    'form' => $form->createView(),
                    'listeInfos' => $listeInfos,
                ));
            }

            // On ajoute un package, donc on offre un téléchargement supplémentaire aux utilisateurs concernés
            $this->getDoctrine()->getManager()->getRepository('PagesBundle:User')->updateNbDDLAll("inc"); 

            //return $this->redirectToRoute('paquets_index'); // Redirection page de gestion de packages
        }

我检索用户在登录表单中输入的密码。 我加密它。然后,我在UserRepository中运行了一个用户名和密码已加密的检查。 如果该函数返回true,则表明有人输入了用户名并输入了加密密码。

我的UserRepository功能:

public function authentifier($username, $password)
    {
        $queryBuilder = $this->createQueryBuilder("u")
        ->select("count(u.id)")
        ->where("u.username = :username")
        ->andWhere("u.password = :password")
        ->setParameter("username",$username)
        ->setParameter("password",$password);
        return $queryBuilder->getQuery()->getSingleScalarResult();
    }
}

但是,security.yml的费用是多少?

1 个答案:

答案 0 :(得分:0)

要检查登录表单上发布的密码是否与数据库中的密码匹配,您只需对其进行加密并检查其是否与数据库中的密码相同。

  • 您从数据库获得了Click add AFNetworking.framework
  • 您对发布的密码进行编码
  • 您检查发布的编码密码是否与User中的密码相同

但是在您的Controller代码中,似乎您创建了一个新用户(您创建了一个从db获取一个新的User插文,并且将其持久化了)?