Авторизация и ограничение доступа в Symfony framework (Урок 14) | Народное программирование

Building a login form

There are a lot of ways that you can allow your users to log in… one way being a login form that loads users from the database. That’s what we’re going to build first.

The easiest way to build a login form system is by running a symfony console make:auth command. That will generate everything you need. But since we want to really learn security, let’s do this step-by-step… mostly by hand.

Before we start thinking about authenticating the user, we first need to build a login page, which… if you think about it… has nothing to do with security! It’s just a normal Symfony route, controller & template that renders a form. Let’s cheat a little to make this. Run:

Answer SecurityController. Cool! Go open up the new class: src/Controller/SecurityController.php:

Nothing too fancy here. Let’s customize this to be a login page: set the URL to /login, call the route app_loginand rename the method to login():

For the template, call it security/login.html.twigand don’t pass any variables right now:

Down in the templates/ directory, open templates/security/and rename the template to login.html.twig:

To get started, I’m going to completely replace this template and paste in a new structure: you can copy this from the code block on this page:

There’s nothing fancy here: we extend base.html.twig, override the title block… then we have a form that submits a POST right back to /login. It doesn’t have an action attribute, which means it submits back to this same URL. The form has two fields – input name="email" and input name="password" – and a submit button… all with Bootstrap 5 classes to look nice.

Let’s add a link to this page from base.html.twig. Search for sign up. Cool. Right before this, add a link with {{ path('app_login') }}, say “Log In”… and give this some classes to make it look nice:

Let’s check it out! Refresh the home page… and click the link. Hello log in page!

And of course, if we fill out the form and submit… absolutely nothing happens! That makes sense. This submits right back to /loginbut because we don’t have any form-processing logic yet… the page just re-renders.

So next: let’s write that processing code. But… surprise! It won’t live in the controller. It’s time to create an authenticator and learn all about Symfony firewalls.

Авторизация и ограничение доступа в symfony framework (урок 14) | народное программирование

Итак, в этой заметке мы научимся ограничивать доступ к разделам сайта, написанного с использованием Symfony framework. Symfony framework предоставляет мощные средства для контроля доступа, которые позволяют ограничивать доступ как по url, так и целым контроллерам.

Если вы путаетесь в понятиях аутентификация, идентификация и авторизация, советую для начала прочитать это.

Сначала немного теории.

То, что нам необходимо, делается с помощью конфигурационного файла (yaml по умолчанию, app/config/security.yml).

Когда пользователь делает запрос до защищенного с помощью firewall url, активируется система защиты.

Процесс аутентификации/авторизации в Symfony framework
Процесс аутентификации/авторизации в Symfony framework

Система сначала определяет, нужна ли аутентификация, если да – тогда возвращает ответ пользователю, инициирующий процесс аутентификации. После введения данных проверяется наличие пользователя, его права, и, если их достаточно, возвращается изначально запрашиваемая страница.

Информация о пользователях может находится как в конфигурационном файле (app/config/security.yml) (если у вас 1-2 пользователя, включая админа – сойдет =)) или в базе данных (если у вас сложная многопользовательская система).

Рассмотрим базовый пример:


# app/config/security.yml
security:
    firewalls:
        secured_area:
            pattern: ^/
            anonymous: ~
        form_login:
            login_path: login
            check_path: login_check
    access_control: - { path: ^/admin, roles: ROLE_ADMIN }
    providers: in_memory: memory: users: ryan: { password: ryanpass, roles: 'ROLE_USER' } admin: { password: kitten, roles: 'ROLE_ADMIN' }
    encoders: SymfonyComponentSecurityCoreUserUser: plaintext

В секции firewalls мы указали, что система защиты активируется для всех входящих запросов, (pattern задает шаблон url`ов), также в следующей строке мы открыли доступ для неавторизированных пользователей.

Параметры form_login login_path и check_path указывают роуты для формы авторизации и проверки данных (Форма – обычный action контроллера, login_check action в простейшем случае описывать не понадобится).

В следующей секции, access_control, мы снова задали шаблон url, но уже для защищенной части ресурса, и указали, какие типы (“роли” в терминах Symfony framework) пользователей имеют доступ к защищенной части.

Следующая секция позволяет указать источники учетных данных пользователей. У примере – прямо в конфигурационном файле. Учтите, что если пароль начинается из цифр, его нужно взять в кавычки. Так же учтите, что получив доступ к конфигурационному файлу, сторонние лица могут легко узнать ваш пароль.

Для отображения логин формы, необходимо создать для нее роутинг. Например, так:

# app/config/routing.yml
login:
  pattern: /login
  defaults: { _controller: AcmeSecurityBundle:Security:login }
login_check:
  pattern: /login_check

И сам action контроллера (взят с официального руководства по Symfony framework):

// src/Acme/SecurityBundle/Controller/SecurityController.php;
namespace AcmeSecurityBundleController;
use SymfonyBundleFrameworkBundleControllerController;
use SymfonyComponentSecurityCoreSecurityContext;
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);
   $session->remove(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)
 );
 }
}

И сам шаблон:


{# src/Acme/SecurityBundle/Resources/views/Security/login.html.twig #}
{% if error %}
    <div>{{ error.message }}</div>
{% endif %}

<form action="{{ path('login_check') }}" method="post"> 
    <label for="username">Username:</label>
    <input type="text" id="username" name="_username" value="{{ last_username }}" />

    <label for="password">Password:</label>
    <input type="password" id="password" name="_password" />
    
    <button type="submit">login</button>
</form>

Итак, мы научились ограничивать доступ к разделам проекта, написанного на  Symfony framework с помощью конфигурационных файлов. Список пользователей сохраняется в этих же файлах. В следующих заметках научимся, как задействовать для этого БД.

Избегайте распространённых ловушек¶

При установке вашей формы входа в систему, будьте осторожны с наиболее
распространёнными ловушками.

Похожее:  Личный кабинет Ростелеком - : вход и регистрация для физических лиц

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *