具有安全性和数据库用户的Symfony 4登录表单 [英] Symfony 4 login form with security and database users

查看:84
本文介绍了具有安全性和数据库用户的Symfony 4登录表单的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大约一周前,我对Symfony完全陌生,我认为我应该只学习Symfony4.经过一周的尝试解决基本登录问题后,我相信文档仍然缺少某些部分.

I was a total noob on Symfony about a week ago and I thought I should just dive in Symfony 4. After a week of trying to solve the basic login problem, I believe the documentation is still missing some parts.

现在,我找到了一个解决方案,并将与您可能在做错事情的一些技巧一起分享.答案的第一部分是建议列表,第二部分是使用从头开始进行有效登录的项目的创建(假设您已经安装了作曲器并使用了apache之类的服务器).

Now I've found a solution and I will share it along with some tips on what you might be doing wrong. First part of the answer is a list of suggestions, while the second part is the creation of a project with working login from scratch (supposing you already have composer installed and using a server like apache).

推荐答案

第1部分:建议

403禁止访问

检查security.yaml中的access_control:密钥.规则的顺序会产生影响,因为每次最多只能匹配一个规则.将最具体的规则放在首位.

Check the access_control: key in security.yaml. The order of the rules has impact, since no more than one rule will match each time. Keep most specific rules on top.

login_check

确保表单操作将您引导至login_check路径,或者将其更改为 security.yaml 中的任何内容.

Make sure the form action sends you to the login_check path, or whatever you changed it to in security.yaml.

还要检查是否已在控制器或 routes.yaml 中声明了login_check路径的路由.

Also check that you have declared a route for the login_check path either in a controller or in routes.yaml.

输入名称

Symfony形式倾向于将输入名称封装在数组中,而只希望它们被命名为_username_password(您可以在 security.yaml 中进行更改)以将其计为登录尝试.因此,请检查输入内容以确保名称属性正确.

Symfony forms tend to encapsulate input names in an array, while it only expects them to be named _username and _password (you can change that in security.yaml) to count it as a login attempt. So inspect the inputs to make sure the name attributes are correct.

让我们从创建项目开始.打开cmd/terminal,然后转到要包含项目文件夹的文件夹.

Let's start by creating the project. Open cmd/terminal and go to the folder you want to contain the project folder.

cd .../MyProjects
composer create-project symfony/website-skeleton my-project
cd my-project

现在,您已经在 .../MyProjects/my-project 中创建了Symfony 4网站模板,cmd/terminal位于该路径中,并将正确执行其余命令.

Now you have created a Symfony 4 website template in .../MyProjects/my-project and the cmd/terminal is in that path and will execute the rest of the commands properly.

在您的 .../MyProjects/my-project/public 文件夹中检查.htaccess文件.如果存在,则可以,请运行以下命令.

Check in your .../MyProjects/my-project/public folder for a .htaccess file. If it exists you are fine, else run the following command.

composer require symfony/apache-pack

您现在可以通过访问 my-project.dev/public 来找到您的站点.如果要删除此公共路径,则应使用 .htaccess 文件,而不要移动 index.php .

You can now find your site by visiting my-project.dev/public. If you want to remove this public path, you should do so using the .htaccess file, not moving the index.php.

1)编辑 .env 文件中的DATABASE_URL键,使其与您的数据库设置相对应.

1) Edit the DATABASE_URL key inside the .env file to correspond to your database settings.

2)编辑 config/packages/security.yaml 文件,如下所示:

2) Edit the config/packages/security.yaml file, so it looks like this:

security:
    encoders:
        App\Entity\User:
            algorithm: bcrypt
    providers:
        user:
            entity:
                class: App\Entity\User
                property: username
    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        main:
            anonymous: true
            provider: user
            form_login:
                #login_path: login
                #check_path: login_check
                default_target_path: homepage
                #username_parameter: _username
                #password_parameter: _password
            logout:
                #path:   /logout
                #target: /
    access_control:
        - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/,      roles: ROLE_USER }
        - { path: ^/admin, roles: ROLE_ADMIN }

一些解释:

App\Entity\User是您将在一段时间内创建的用于处理登录的用户实体.

App\Entity\User is the User entity you 'll create in a while to handle the login.

user提供程序只是一个名称,需要在提供程序和防火墙中匹配.

The user provider is just a name that needs to have a match in providers and firewalls.

如果要允许用户...退出,必须声明logout键.

The logout key must be declared if you want to allow the user to... well, logout.

#comment中的值显示了我们稍后将使用的默认值,并作为您更可能更改的内容的参考.

Values in #comment reveal the default value we'll be using later on and act as a reference of what you are more likely to change.

用户必须具有角色,但可以具有更多角色.因此,让我们首先为ManyToMany关系建立一个UserRole实体.

A user must have a role, but could have more. So let's build a UserRole Entity first for a ManyToMany relationship.

php bin/console make:entity userRole

所有实体均以id属性开头.还要添加一个role.

All entities start with an id property. Add a role too.

php bin/console make:entity user

用户需要usernamepasswordroles属性,但是您可以添加更多内容.

User needs the username, password and roles properties, but you can add more.

让我们编辑 src/Entity/User.php 文件:

UserInterface接口添加到您的User类中.

Add the UserInterface interface to your User class.

use Symfony\Component\Security\Core\User\UserInterface;
class User implements UserInterface

编辑生成的getRoles(),以使其返回字符串数组.

Edit the generated getRoles(), to make it return string array.

public function getRoles(): array
{
    $roles = $this->roles->toArray();
    foreach($roles as $k => $v) {
        $roles[$k] = $v->getRole();
    }
    return $roles;
}

getSalt()eraseCredentials()是用于实现UserInterface接口的功能.

getSalt() and eraseCredentials() are functions to implement the UserInterface interface.

public function getSalt()
{
    return null;
}
public function eraseCredentials()
{
}

使用bcrypt算法(如我们在 security.yaml 中设置的),我们不需要加盐.它会自动生成一个.不,您不会在任何地方存储此盐,是的,每次相同的密码都会产生不同的哈希值.但是,是的,它将以某种方式起作用(魔术...).

Using the bcrypt algorithm (as we set in security.yaml) we don't need a salt. It generates automatically one. No, you don't store this salt anywhere and yes, it will produce different hash for the same password every time. But yes, it will work somehow (magic...).

如果需要使用盐的其他算法,则需要在User实体上添加salt属性.

If you need a different algorithm, that uses salt, you need to add a salt property on the User entity.

出于测试目的,我们将创建一个主页

For testing purposes we will create a homepage

php bin/console make:controller homepage

编辑生成的 src/Controller/HomepageController.php 文件,将根目录更改为/

Edit the generated src/Controller/HomepageController.php file to change the root to /

@Route("/", name="homepage")

登录控制器

php bin/console make:controller login

编辑生成的 src/Controller/LoginController.php 文件,使其如下所示:

Edit the generated src/Controller/LoginController.php file to make it like this:

<?php

namespace App\Controller;

use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use App\Form\LoginType;

class LoginController extends Controller
{
    /**
     * @Route("/login", name="login")
     */
    public function index(AuthenticationUtils $authenticationUtils)
    {
        $error = $authenticationUtils->getLastAuthenticationError();
        $lastUsername = $authenticationUtils->getLastUsername();
        $form = $this->createForm(LoginType::class);
        return $this->render('login/index.html.twig', [
            'last_username' => $lastUsername,
            'error'         => $error,
            'form'          => $form->createView(),
        ]);
    }

    /**
     * @Route("/logout", name="logout")
     */
    public function logout() {}

    /**
     * @Route("/login_check", name="login_check")
     */
    public function login_check() {}
}

登录表格

php bin/console make:form login

您不必将其关联到User实体.

You don't have to associate it to the User entity.

编辑生成的 src/Form/LoginType.php 文件以添加此文件:

Edit the generated src/Form/LoginType.php file to add this:

use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;

替换此:

$builder
    ->add('_username')
    ->add('_password', PasswordType::class)
    ->add('login', SubmitType::class, ['label' => 'Login'])
;

并添加此功能,以防止Symfony通过将它们包含在login[...]

and add this function, to prevent Symfony from changing the input names you requested above by enclosing them in login[...]

public function getBlockPrefix() {}

登录模板

编辑 templates/login/index.html.twig 文件,以将该代码添加到{% block body %} ... {% endblock %}:

Login Template

Edit the templates/login/index.html.twig file to add this code in the {% block body %} ... {% endblock %}:

{% if error %}
    <div>{{ error.messageKey|trans(error.messageData, 'security') }}</div>
{% endif %}
{{ form_start(form, {'action': path('login_check'), 'method': 'POST'}) }}
    {{ form_widget(form) }}
{{ form_end(form) }}

数据库生成

php bin/console doctrine:migrations:generate
php bin/console doctrine:migrations:migrate

这应该已经根据您的UserUserRole实体生成了数据库.

This should have generated your database, according to your User and UserRole entities.

以下命令将为您提供可以直接插入数据库的哈希密码.密码将使用 security.yaml 中指定的算法进行哈希处理.

The following command will provide you with a hashed password you can directly insert into the database. The password will be hashed with the algorithm specified in security.yaml.

php bin/console security:encode-password my-password

希望这会有所帮助!

这篇关于具有安全性和数据库用户的Symfony 4登录表单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆