Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel handle user redirection in trait based on role

Tags:

php

laravel

I am using Laravel Auth and Socialite package for social login. I also have different user roles and redirecting them on separate pages based on roles.

Handling redirection for Auth logged in user from LoginController > authenticated() method.

LoginController

public function authenticated(Request $request, $user)
{
    if (auth()->check()) {
        if (in_array($user->role, $this->getAdminRoles())) {
            return redirect(route('admin.dashboard'));
        }
    }
}

It is working correctly and redirecting the user based on their role. However, that only works if they login in the traditional way.

If the user login using any social channel, the redirection doesn't work. I realize that the Social Login redirection Handel from its handler method. For that, I have a trait as below. So I can use it on RegisterController to avoid code duplication.

SocialAuthHandler Trait

namespace App\Traits;

use App\SocialProvider;
use App\User;
use DateTime;
use Exception;
use Illuminate\Support\Facades\Auth;
use Laravel\Socialite\Facades\Socialite;

use function is_null;
use function preg_replace;
use function redirect;
use function strtolower;

trait SocialAuthHandler
{
    /**
     * Redirect the user to the GitHub authentication page.
     *
     * @param $provider
     *
     * @return \Illuminate\Http\Response|\Symfony\Component\HttpFoundation\RedirectResponse
     */
    public function redirectToProvider($provider)
    {
        return Socialite::driver($provider)->redirect();
    }

    /**
     * Obtain the user information from GitHub.
     *
     * @param $provider
     *
     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\Response|\Illuminate\Routing\Redirector
     * @throws \Exception
     */
    public function handleProviderCallback($provider)
    {
        try {
            $socialUser = Socialite::driver($provider)->user();
        } catch (Exception $e) {
            return redirect('/');
        }

        //
        $socialProvider = SocialProvider::where('provider_id', $socialUser->getId())->first();

        if (!$socialProvider) {
            $username = $socialUser->getNickname();
            $name     = $socialUser->getName();

            if (!isset($userNickname) || is_null($userNickname)) {
                if (isset($name) && !is_null($name)) {
                    $username = strtolower(preg_replace('/\s+/', '', $name));
                } else {
                    $timeStamp = new DateTime('now');
                    $username  = $timeStamp->format('U');
                }
            }

            //create user
            $user = User::firstOrCreate(
                ['email' => $socialUser->getEmail()],
                ['username' => $username]
            );

            // mark email is verified
            // for social logged in users
            $user->markEmailAsVerified();

            $user->socialProviders()->create(
                [
                    'provider_id' => $socialUser->getId(),
                    'provider'    => $provider,
                ]
            );
        } else {
            $user = $socialProvider->user;
        }

        // log in user
        Auth::login($user, TRUE);

        return redirect($this->redirectTo);
    }
}

Question: is how can I handle redirection on the social handler so the user will redirect based on their role. If the admin then admin/dashboard or if the user then home?

Well, most likely this might not happen on the first time user login as the default role will be user but later whenever they log in after assigned different role

like image 250
Code Lover Avatar asked Nov 06 '22 09:11

Code Lover


1 Answers

In your SocialAuthHandler trait, you are simply redirecting to the redirectTo property without checking for the user's role. You could achieve the same behaviour by calling the authenticated method.

Replace:

return redirect($this->redirectTo);

By:

return $this->authenticated(request(), $user) ?: redirect($this->redirectTo);
like image 64
Chin Leung Avatar answered Nov 14 '22 22:11

Chin Leung