Symfony internals and security
Tags: symfony, beginners, security, php
Published: 2023-05-13 15:37:57

Symfony is a PHP framework that is recommended by many devs, as it focuses on best practices.

Let's see how it works behind the scene (in short).

## Symfony is HTTP-centric

You may have already seen some calls to the `Kernel` in `public/index.php`.

When you open a page (e.g., the home page but other pages as well), the main index file calls the kernel which triggers a `RequestEvent` and calls resolvers to determine which controller matches the request (~ the URL).

As the name suggests, the controller will articulate the process, passing data and arguments between views and models. 

Symfony works with a database, so a typical request will likely involve a database query, which is handled by a "repository" and one of the `find*` methods (e.g., `findAll()`). 

Behind the scene, the framework uses PDO to interact with the database in a standardized way.

Once it has pulled the data, Symfony can return a `ResponseEvent` and render the view using its template engine Twig.

Of course, your app may leverage additional layers, like caches or a noSQL system like Redis, which prevents direct calls to the database every time you need to render something.

It's particularly helpful to handle traffic peaks and user sessions.

## Other ways to discover Symfony internals

Symfony has such a great documentation and a large community, so it's unlikely you won't find what you're looking for as a beginner.

Most common errors are documented on the official documentation itself, but you can also leverage stackoverflow and other dedicated platforms for devs.

Although, you may also use the native Symfony console, Xdebug or [a profiler](https://symfony.com/doc/current/profiler.html) **before**, to figure it out on your own or **ask better questions**. 

Besides, you can install several bundles to profile Symfony:

```
composer require --dev symfony/profiler-pack
```

## Security rules

Symfony has [various internal mechanisms](https://symfony.com/doc/current/security.html) you can leverage to secure your project.

You can use the SecurityBundle, which is a "tight integration of the Security component":

```
composer require symfony/security-bundle
```

Most apps require authentication and user permissions. Even if you don't have to manage user sessions, you can't skip security:

```yaml
    access_control:
	- { path: ^/admin/login, roles: PUBLIC_ACCESS }
        - { path: '^/admin', roles: ROLE_ADMIN }
```

The `security.yaml` file can be configured to protect your app against common attacks, hash & verify passwords, manage cookies and even set firewalls, which are listeners of the HTTP component.

The console can also save you some time if you need to build login forms and authenticators:

```
 php bin/console make:auth
 php bin/console make:controller Login
```

However, keep it mind it only provides generic starters that promote good practices, nothing more.

## Beyond firewalls: voters and passports

[**The Voter system**](https://github.com/symfony/symfony/blob/6.2/src/Symfony/Component/Security/Core/Authorization/Voter/Voter.php) allows "centralizing all **permission logic**, then reuse them in many places." 

It triggers every time you use the `isGranted()` method in a controller or [access controls](https://symfony.com/doc/current/security/access_control.html#security-access-control-enforcement-options), but you can also define your own voters (~ custom access strategies).

[**Passports**](https://github.com/symfony/symfony/blob/6.2/src/Symfony/Component/Security/Http/Authenticator/Passport/Passport.php) are objects that contain user credentials and badges (~ additional pieces of information, like the `rememberMeBadge`) used by the Security component during the authentication.

## Where should I write security instructions?

The security bundle is very flexible and allows defining custom rules in various files: configs (e.g., `security.yaml`), controllers, services, even in templates (e.g., `isGranted()` in Twig).

Although, it can be hard to determine where exactly to write your rules to keep things readable and maintainable. Unfortunately, there's no magic recipe you can apply blindly:

* you will have to define rules in the general config file
* you might need custom annotations in your controllers
* in practice, it's usually a mix of both, and other approaches may even intercept requests at a higher level, skipping controllers

## Wrap this up

You can discover how Symfony does its magic by profiling your app and enabling critical security mechanisms, like user sessions and permissions.