Auth controller helper


1Presentation

This helper is used to manage the authentication of website users. It is both the controller that provides the interface for authentication, and the plugin that transmits authentication information to other plugins/controllers.

The proposed authentication system is password-free: the user enters his e-mail address, and if it is known in the database, a message is sent to this address, containing a link. By clicking on the link, the user returns to the site as authenticated. The link can only be used once, and has a limited lifetime of one hour.

By default, the controller only accepts connections from users who have already been added to the database. However, it can be configured so that new users are registered when they enter their e-mail address for the first time.


2Database

This helper requires two database tables, one named User (containing user information), the other named AuthToken (containing connection tokens sent by email).

The User table must contain the following fields:

  • id (int): Primary key.
  • date_creation (datetime): User creation date.
  • date_last_login (datetime): Date of user's last authentication.
  • date_last_access (datetime): Date of user's last access.
  • email (string): User's email address.
  • name (string): User name (mandatory field, even if you don't use it).
  • roles (set): Roles assigned to the user.
  • services (set): Services to which the user has access.

The AuthToken table must contain the following fields:

  • token (string): Digest message (SHA-256 algorithm) of the connection token.
  • expiration (datetime): The token's expiration date and time.
  • user_id (int): Foreign key to the user.

Here's an example of a query to create these tables, for which you need to customize the roles and services fields of the User table:

CREATE TABLE User (
    id               INT UNSIGNED NOT NULL AUTO_INCREMENT,
    date_creation    DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    date_last_login  DATETIME,
    date_last_access DATETIME,
    email            TINYTEXT CHARACTER SET ascii COLLATE ascii_general_ci NOT NULL,
    name             STRING,
    roles            SET('admin', 'writer', 'reviewer'), -- must be personalized
    services         SET('articles', 'news', 'images'), -- must be personalized
    PRIMARY KEY (id),
    UNIQUE INDEX email (email(255))
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

CREATE TABLE AuthToken (
    token         CHAR(64) CHARACTER SET ascii COLLATE ascii_general_ci NOT NULL,
    expiration    DATETIME NOT NULL,
    user_id       INT UNSIGNED NOT NULL,
    PRIMARY KEY (token),
    INDEX expiration (expiration),
    FOREIGN KEY (user_id) REFERENCES User (id) ON DELETE CASCADE
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

3Plugin and controller configuration

You need to add the \Temma\Controllers\Auth object as a pre-plugin in the Temma configuration, and create a route to make the controller accessible:

[
    'plugins' => [
        '_pre' => [
            '\Temma\Controllers\Auth'
        ]
    ],
    'routes' => [
        'auth' => '\Temma\Controllers\Auth'
    ]
]

4Configuration of connection messages

Here are the default parameters used to send connection messages:

  • Sender's email address: contact@ + domain name of your site
  • Message title: Your connection link
  • Message text:
    Hi,
    
    Here is your connection link:
    %s
    
    It is valid for 1 hour and can only be used once.
    
    Best regards

These parameters can be modified:

[
    'x-security' => [
        'auth' => [
            'emailSender'  => 'no-reply@mycompany.com',
            'emailSubject' => 'Here is your magic link!',
            'emailText'    => 'Click on this link to get connected: %s',
        ]
    ]
]
  • Line 4: Message sender's e-mail address.
  • Line 5: Connection message title.
  • Line 6: Message content, in plain text. The %s marker is replaced by the connection URL.

The controller uses the \Temma\Utils\Email object to send connection messages. It is therefore possible to use the configuration of this object to disable sending, to authorize only sending to certain domains, or to add recipients as copies or blind copies.


5Configuration of user registration

To automatically register users who are not in the database, simply add this configuration:

[
    'x-security' => [
        'auth' => [
            'registration' => true
        ]
    ]
]

6Configuration of redirections

By default, once a user is authenticated, they are redirected to the site's homepage. It is possible to configure a different URL:

[
    'x-security' => [
        'auth' => [
            'redirection' => '/myAccount'
        ]
    ]
]

Note that if a session variable named authRequestedUrl exists, its contents will be used to perform the redirection (and the variable is deleted from the session). This variable can be defined by the Auth attribute, if its storeUrl parameter is set to true.


7Database configuration

By default, table and field names are those indicated above, and these tables must be placed in the database opened by the connection named db in the dataSources configuration directive. You have the option of specifying the database name, table names and field names, if different from the default:

[
    'x-security' => [
        'auth' => [
            'userData' => [
                'base'     => 'auth_app',
                'table'    => 'tUser',
                'id'       => 'user_id',
                'email'    => 'user_mail',
                'roles'    => 'user_roles',
                'services' => 'user_services',
            ],
            'tokenData' => [
                'base'       => 'auth_app',
                'table'      => 'tToken',
                'token'      => 'token_string',
                'expiration' => 'expiration_date',
                'user_id'    => 'identifier_user',
            ]
        ]
    ]
]
  • Lines 4 to 12: User table configuration.
    • Line 5: Name of the database containing the table.
    • Line 6: Table name.
    • Line 7: Name of field containing primary key.
    • Line 8: Name of the field containing the user's e-mail address.
    • Line 9: Name of the field containing user roles.
    • Line 10: Name of the field containing the services to which the user has access.
  • Lines 12 to 18: Connection token table configuration.
    • Line 13: Name of the database containing the table.
    • Line 14: Table name
    • Line 15: Name of the field containing the token.
    • Line 16: Name of the field containing token expiration date.
    • Line 17: Name of the field containing user identifier.

If the user table contains other fields you wish to retrieve, you can add them to the list. If the fields are not to be renamed, set the key and value to the same name:

[
    'x-security' => [
        'auth' => [
            'userData' => [
                'email'        => 'user_mail',
                'name'         => 'user_name',
                'organization' => 'organization',
                'birthday'     => 'birthday',
            ]
        ]
    ]
]
  • Line 5: Name of the field containing the user's e-mail address.
  • Line 6: user_name field added, renamed to name.
  • Line 7: organization field added, not renamed.
  • Line 8: birthday field added, not renamed.

8Database configuration using DAOs

Rather than using the configuration file (etc/temma.php) to define database parameters, it is possible to use custom DAOs.

Configuration example:

[
    'x-security' => [
        'auth' => [
            'userDao'  => '\MyApp\UserDao',
            'tokenDao' => '\MyApp\TokenDao',
        ]
    ]
]

DAO example:

namespace MyApp;

class UserDao extends \Temma\Dao\Dao {
    protected $_tableName = 'tUser';
    protected $_idField = 'use_i_id';
    protected $_fields = [
        'user_id'       => 'id',
        'user_mail'     => 'email',
        'user_roles'    => 'roles',
        'user_services' => 'services',
        'user_name'     => 'name',
        'organization',
        'birthday',
    ];
}

9Controller URLs

The controller offers the following URLs:

  • /auth/login: Page displaying the authentication form.
  • /auth/logout: URL to send the user to for logout.

The /auth URL redirects to /auth/login.


10Template

The controller uses a Smarty template located in templates/auth/login.tpl. The version supplied by Temma is minimal, and we recommend that you use it as a basis for creating your own version.


11Template variables

The plugin sets the following template variables:

  • currentUserId: Identifier of the currently authenticated user.
  • currentUser: Data of the current user. This is an associative array containing the following keys:
    • id: User's identifier.
    • date_creation: Date of user creation.
    • date_last_login: Date of user's last authentication.
    • date_last_access: Date of user's last access.
    • email: User's email address.
    • name: User name.
    • roles: Associative array whose keys are the user's roles (associated with the value true).
    • services: Associative array whose keys are the services to which the user has access (associated with the value true).

These variables can be used in other plugins, controllers and templates.


12Auth attribute

Temma provides the Auth attribute, which allows you to specify whether a controller or action can only be accessed by an authenticated user (or not). As this attribute is based on the presence of a currentUser template variable (as well as its roles and services keys), it is fully compatible with this helper.

For example, you can specify that a controller is only accessible to logged-in users:

use \Temma\Attributes\Auth as TµAuth;

#[TµAuth]
class Account extends \Temma\Web\Controller {
    // ...
}

It is also possible to restrict access to controllers or actions to users with a specific role or access to a specific service:

use \Temma\Attributes\Auth as TµAuth;

class MonControleur extends \Temma\Web\Controller {
    // access authorized only to users with
    // the "manager" role
    #[TµAuth('manager')]
    public function action1() { }

    // authorized only to users with access
    // to the "images" or "text" services
    #[TµAuth(service: ['images', 'text'])]
    public function action2() { }
}

Refer to the attribute documentation to see all its capabilities.