DEV Community

Cover image for Fortify: How to Disable Auto-login After User Registration
Faruk Nasir
Faruk Nasir

Posted on

Fortify: How to Disable Auto-login After User Registration

With Fortify, a user is logged in, automatically, after registration. This might not be what you want for your application. Thankfully, the package is easily extensible.

This post is a walk-through on how to override the default behaviour and disable the auto-login.

Before we start, let's take a look at the package and try to understand what is happening behind the curtain. You register a user by hitting the /register endpoint with the expected name, email, password and password_confirmation fields' values. On a successful login, you get redirected to the home configuration option in your fortify's configuration file. The controller responsible for handling the registration request is RegisteredUserController. Inside the controller class, there is another method–store that handles the actual registration:

/**
 * Create a new registered user.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  \Laravel\Fortify\Contracts\CreatesNewUsers  $creator
 * @return \Laravel\Fortify\Contracts\RegisterResponse
 */
public function store(Request $request,
                        CreatesNewUsers $creator): RegisterResponse
{
    event(new Registered($user = $creator->create($request->all())));

    $this->guard->login($user);

    return app(RegisterResponse::class);
}
Enter fullscreen mode Exit fullscreen mode

You can see that the registered user is logged in right after firing the Registered event.

$this->guard->login($user);
Enter fullscreen mode Exit fullscreen mode

A noob mentality will have you thinking you can easily comment out that line and you're good to go. Well, you could do that and your code temporarily behaves as expected but what happens when you run composer update/install and your change is overridden––You are back to square one. You should never make changes to any code within the confines of the vendor folder.

Create a folder and name it Responses inside the Http folder of your application. Inside, create a RegisterResponse class that extends the FortifyRegisterResponse class.

<?php

namespace App\Http\Responses;

use Illuminate\Http\JsonResponse;
use Illuminate\Http\Response;
use Laravel\Fortify\Contracts\RegisterResponse as RegisterResponseContract;

class RegisterResponse extends FortifyRegisterResponse
{
    /**
     * Create an HTTP response that represents the object.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Symfony\Component\HttpFoundation\Response
     */
    public function toResponse($request)
    {
        return $request->wantsJson()
                    ? new JsonResponse('', 201)
                    : redirect()->intended(config('fortify.home'));
    }
}
Enter fullscreen mode Exit fullscreen mode

Take out everything inside the toResponse method and replace it with code that will first log out the just logged in user by Fortify and then defers to the base class's implementation:

<?php

namespace App\Http\Responses;

use Illuminate\Contracts\Auth\StatefulGuard;
use Laravel\Fortify\Http\Responses\RegisterResponse as FortifyRegisterResponse;

class RegisterResponse extends FortifyRegisterResponse
{
    protected $guard;

    public function __construct(StatefulGuard $guard)
    {
        $this->guard = $guard;
    }

    public function toResponse($request)
    {
        $this->guard->logout();

        return parent::toResponse($request);
    }
}
Enter fullscreen mode Exit fullscreen mode

Fortify's RegisteredUserController accepts a stateful guard implementation on it's constructor. So, we are using the same approach so that the response object receives the same guard instance as that of the controller. Otherwise, we could have used the Auth facade to logout the user.

The final step is to register the implementation in Fortify's service provider's boot method as in the following:

/**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        ...

        $this->app->singleton(
            \Laravel\Fortify\Contracts\RegisterResponse::class,
            \App\Http\Responses\RegisterResponse::class,
        );
    }
Enter fullscreen mode Exit fullscreen mode

And that's all, folks!

This post appeared here first.

Top comments (0)