【问题标题】:Laravel 5 Socialite - change auth redirect path dynamicallyLaravel 5 Socialite - 动态更改身份验证重定向路径
【发布时间】:2015-05-21 13:09:51
【问题描述】:

我正在尝试将社交名流整合到一个网站中,但遇到了一个问题,这应该是一件相当微不足道的事情 - 更改用户在通过社交提供者身份验证后重定向的位置。

我将使用社交名流来执行三个操作:

  • 注册 - 向提供商进行身份验证,然后重定向到注册表单。为他们填写了他们的姓名和电子邮件地址,需要更多字段。
  • 登录 - 典型的登录场景,根据用户表检查提供者信息,如果匹配则登录
  • 链接 - 用户已有活动帐户,但想链接外部(Faceebook 或 Google)帐户。这将对用户进行身份验证并将正确的社交媒体 ID 添加到用户表中的行。 问题是您在 services.php 文件中指定了身份验证重定向,我无法弄清楚在成功通过第三方提供商身份验证后如何更改用户重定向的位置。

这是我目前所拥有的 -

路由:这似乎在社交提供者重定向时起作用,因为缺少driver=facebook&action=login(例如)。理想情况下,我想指定在发出初始身份验证请求时将用户重定向到哪里——这只是我第一次尝试解决这个问题。

get('social-auth', function(AuthenticateUser $authenticateUser, Request $request) {
    $driver = $request->input('driver');
    $action = $request->input('action');

    return $authenticateUser->execute($request->has('code'), $driver, $action);
});

AuthenticateUser 类 - 希望这里的 cmets 就足够了:

<?php namespace App;

use Illuminate\Database\Eloquent\ModelNotFoundException;
use Laravel\Socialite\Contracts\Factory as Socialite;
use Auth;
use Flash;

class AuthenticateUser
{
    /**
     * @var Socialite
     */
    private $socialite;
    /**
     * @var Auth
     */
    private $auth;

    public function __construct(Socialite $socialite, Auth $auth)
    {

        $this->socialite = $socialite;
        $this->auth = $auth;
    }

    /**
     * @param boolean $hasCode Whether or not we have been authenticated already
     * @param string $driver Driver to use, Facebook or Google
     * @param string $type Type of call - Login, Register, or Link
     * @return array|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
     */
    public function execute($hasCode, $driver, $type)
    {
        if (!$hasCode) {
            return $this->getAuthorizationFirst($driver);
        }

        // Get the User details from the Social Provider
        $socialUser = $this->socialite->driver($driver)->user();
        $socialUserArray = $socialUser->user;

        if ($driver == 'facebook') {
            // Get Facebook specific fields
            $first_name = $socialUserArray['first_name'];
            $last_name = $socialUserArray['last_name'];
        } else if ($driver == 'google') {
            // Get Google specific fields
            $first_name = $socialUserArray['name']['givenName'];
            $last_name = $socialUserArray['name']['familyName'];
        }
        $email = $socialUser->email;
        $id = $socialUser->id;

        // Perform an action - login, register, or link
        switch ($type) {
            case 'login':
                // Log the user in with the Facebook ID
                try {
                    if ($driver == 'facebook') {
                        $user = User::whereFacebookAuth($id)->firstOrFail();
                    } else {
                        $user = User::whereGoogleAuth($id);
                    }
                } catch (ModelNotFoundException $e) {
                    flash::error('Could not find a user associated with this ' . ucfirst($driver) . ' account.');
                    return redirect('auth/login');
                }
                Auth::login($user);
                return redirect('members');
                break;
            case 'register':
                // Register using social media account
                return redirect('register')
                    ->with('social_type', $driver)
                    ->with('social_id', $id)
                    ->with('email', $email)
                    ->with('first_name', $first_name)
                    ->with('last_name', $last_name);
                break;
            case 'link':
                // Associate this Social Media account with the current User
                $driver == 'facebook' ? Auth::user()->facebook_auth = $id : Auth::user()->google_auth = $id;
                Auth::user()->save();
                return ['status' => 'success'];
                break;
        }
    }

    /**
     * Authorize the user before proceeding
     * @param $driver
     * @return mixed
     */
    private function getAuthorizationFirst($driver)
    {
        return $this->socialite->with($driver)->redirect('hopefully-somewhere-else'); 
    // Anything inside redirect doesn't seem to do anything
    }
}

【问题讨论】:

标签: laravel laravel-5 laravel-socialite


【解决方案1】:

我倾向于在我的网址中包含提供商。例如:

Route::get('auth/{provider}', 'AuthController@redirectToProvider');
Route::get('auth/{provider}/callback', 'AuthController@handleProviderCallback');

这样我就可以从控制器操作中的请求中访问提供者名称:

public function callback($provider)
{
    $user = $this->socialite->driver($provider)->getUser();

    try {
        // Try and find user by their social profile UID
        $appUser = SocialAccount::whereUid($user->getId())
            ->whereProvider($provider)
            ->firstOrFail();

        Auth::loginUsingId($appUser->user_id);
    } catch (ModelNotFoundException $e) {
        if (Auth::user()) {
            // Attach social profile to logged in user
        } else {
            // User is not logged in, and account does not exist
            // Prompt to register
        }
    }
}

【讨论】:

  • 感谢您的回答,但提供者部分并不是最大的问题,它处理多个操作 - 登录、注册和链接(如问题中所述)。我能想到的唯一一件事是在 services.php 中为每个驱动程序都有一个驱动程序,每个驱动程序都有一个重定向路径(登录、注册、链接),但必须有更好的方法
  • 您通常会有一个回调来检查第三方帐户是否已用于登录,如果是,则只需登录相应的用户。如果没有并且用户已登录,请附加社交帐户到他们的个人资料。否则,请提供注册表(其中包含从社交资料中预先填写的数据)和字段以获取您网站所需的任何其他信息。
  • 这是一个高度受限的站点,因此所有新成员必须在登录前获得批准(安全要求)。如果用户单击“向 注册”,系统将提示他们授权该站点,然后将其重定向到注册表单,并在表单中预先填写了他们的详细信息。如果他们已经有一个活动帐户,我希望他们以后能够链接一个社交帐户。第三种场景是简单的登录。所以我需要有多个重定向路径到我的应用程序来处理这些不同的场景。
  • 此外,我网站上的用户电子邮件地址可能与他们选择的社交提供商的电子邮件地址不匹配(也可能不会) - 所以我将根据他们的用户 ID 而不是提供商报告的电子邮件地址.这就是为什么我需要这些信息以便以后注册和链接。
  • 哈哈,别担心。很高兴能帮上忙。
【解决方案2】:

迟到加入聚会,但可能会帮助别人。如果您想处理多个重定向,例如登录、注册、将社交帐户链接到用户个人资料,可以通过从控制器端覆盖服务配置来完成。

config(['services.google.redirect' => <Your New URL here> ]);
Socialite::driver('google')->redirect();

注意:- 有些社交平台严格要求将 URL 重定向到他们的开发者控制台。因此,您需要在此处提及每个重定向 URL。

【讨论】:

    猜你喜欢
    • 2016-04-06
    • 1970-01-01
    • 1970-01-01
    • 2017-01-24
    • 2015-06-08
    • 1970-01-01
    • 2015-08-21
    • 2016-07-25
    相关资源
    最近更新 更多