基于角色的trait中,Laravel如何处理用户重定向?

6

我正在使用Laravel Auth和Socialite包进行社交登录。我还有不同的用户角色,并根据角色将他们重定向到不同的页面。

LoginController > authenticated()方法中处理已认证登录用户的重定向。

LoginController

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

它可以正确地工作并根据用户角色重定向用户。但是,只有在传统方式下登录时才起作用。

如果用户使用任何社交渠道登录,则重定向不起作用。我意识到Social Login重定向处理器从其处理程序方法中处理。因此,我有一个如下的trait。因此,我可以在RegisterController上使用它以避免代码重复。

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);
    }
}

问题:如何在社交处理程序上处理重定向,使用户根据其角色重定向。如果是管理员,则是admin/dashboard,如果是用户,则回到主页?

很可能这不会发生在用户第一次登录时,因为默认角色将是用户,但稍后当他们在分配了不同的角色之后登录时会出现。


具体是哪个Laravel版本? - felipsmartins
@felipsmartins 我正在使用最新的(当前的)版本6.*。 - Code Lover
1个回答

1
在您的SocialAuthHandler trait中,您只是简单地重定向到redirectTo属性,而没有检查用户的角色。您可以通过调用authenticated方法来实现相同的行为。
return redirect($this->redirectTo);

通过:

return $this->authenticated(request(), $user) ?: redirect($this->redirectTo);

谢谢您的帮助。然而,它给出了以下错误信息。“ErrorException:头信息不能包含超过一个头,检测到换行符”。 - Code Lover
@CodeLover 你尝试使用的用户是管理员吗?你能展示一下更新后的控制器吗? - Chin Leung
完美。已解决。只是想了解一下..是什么导致了错误? - Code Lover
@CodeLover 因为您的用户很可能不是管理员,在您的authenticated方法中没有后备方案。因此,我为在authenticated方法中没有任何操作的用户添加了?: redirect($this->redirectTo); - Chin Leung
我明白了。所以如果我在authenticated()方法中设置else条件而不是在SocialHandler方法中设置,那么也应该可以工作。对吗? - Code Lover

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接