1

I need some help with my login process, it's working but I feel it's not the best approach to achieve it

I have the following workflow for the Login process :

1- enter username/password -> press login

2- check for a cookie id if this is a new device/browser verify the user's phone number.

3- after verifying -> redirect to the login page to enter credentials again and continue login.

My module code :

1- VerifySMS controller: I'm saving a unique cookie to identify the user device later.

2- inside module init()

Event::on(
        User::class,
        User::EVENT_BEFORE_AUTHENTICATE,
        function (AuthenticateUserEvent $event) {
            $newDevice = "check if it's new device using cookies";
            if ($newDevice) {
                $event->sender->authError = "Error";
                Craft::$app->getResponse()->redirect('to verify phone number controller');
            }
        }
    );

Right now I'm checking for a new device before authenticating and i need to repeat the login again after I verify the number.

I need to do it like this:

First validating username/password --> if True then check for a new device --> if True then verify the phone number and after this proceed with the login directly to the home page(authenticate) without needing to require username/pass again ??

I hope that I explained it clear enough.

Thank you all

1 Answer 1

1

This is definitely attacking the problem from a different angle, and it might not be a good idea for your overall application – hard to say without knowing more about the specifics.

But, an alternative, and possibly simpler, approach to interfering with Craft's authentication flow could be to add some logic to your module's init() method that checks (on every web request) if a) the current user is logged in, b) if they should (re)verify their phone number and c) redirects the user to the SMS verification controller if that's the case.

Something like this:

use craft\web\Application;
use yii\base\Event;

Event::on(
    Application::class,
    Application::EVENT_INIT,
    static function (Event $event) {

        // Is the user logged in?
        $currentUser = Craft::$app->getUser()->getIdentity();
        if (!$currentUser) {
            return;
        }

        // Check if the user is using a "new device"
        $newDevice = "check if it's new device using cookies";
        if (!$newDevice) {
            return;
        }

        // Redirect to the SMS verification controller
        // If you wanted to redirect the user back to the page they were trying to access, after verifying, Craft::$app->getRequest()->getAbsoluteUrl() will give you the current request URL

        Craft::$app->getResponse()->redirect('to verify phone number controller');
        
    }
);

Obviously there are a lot of possible wrinkles to the above – for one, if the SMS verification is done via an onsite endpoint, you'll probably need to add some logic to avoid an infinite redirect loop (maybe by checking Craft::$app->getRequest()->getActionSegments() or something, or possible disabling the logic altogether for action requests by adding a check for Craft::$app->getRequest()->getIsActionRequest()).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.