Laravel Socialite - разные провайдеры с одним и тем же адресом электронной почты - безопасность, как исправить

Хорошо, я прочитал, как внедрить Laravel socialite в свое приложение, чтобы позволить пользователям входить в систему с помощью Google или Facebook. Я прочитал, как это сделать, здесь. Проблема, с которой я сталкиваюсь с этим подходом, заключается в том, что если пользователь входит, скажем, из Google с адресом электронной почты [email protected], а затем входит в систему из Facebook, используя [email protected], он входит в ту же учетную запись! Право на безопасность. Поэтому я подумал, что, прежде чем позволить им войти в систему, я проверю идентификатор поставщика, который вы можете получить, однако, когда я пытаюсь сравнить provider_id, который я храню в базе данных, когда они создают учетную запись с provider_id, хранящимся в переменной пользователя socialite, я получить эту ошибку:

Аргумент 1, переданный в Illuminate \ Auth \ SessionGuard :: login (), должен реализовывать интерфейс Illuminate \ Contracts \ Auth \ Authenticatable, задан экземпляр Illuminate \ Http \ RedirectResponse

Вот весь код, который я использую для Socialite:

<?php

namespace App\Http\Controllers;
use Socialite;
use App\User;
use Auth;
use Illuminate\Support\Facades\Redirect;
use Flash;
use Illuminate\Http\Request;
use App\Http\Requests;

class SocialiteController extends Controller
{

    public function redirectToProvider($provider)
    {
        return Socialite::driver($provider)->redirect();
    }

    public function handleProviderCallback($provider)
    {
        try
        {
            $social_user = Socialite::driver($provider)->user();
        }
        catch(Exception $e)
        {
             return Redirect::to('auth/' . $provider);
        }
        $authUser = $this->findOrCreateUser($social_user);
        Auth::login($authUser, true);
        flash()->overlay('You have been logged in successfully!', 'Congratulations');
        return Redirect::to('/');

    }
    //create a new user in our database or grab existing user
    private function findOrCreateUser($social_user)
    {
        if ($authUser = User::where('email', $social_user->email)->first()) {
            //this creates an error
            if($authUser->provider_id == $social_user->id)
                return $authUser;
            else
            {
                flash()->overlay('An account for that email already exists!', 'Error');
                return Redirect::to('/');
            }
        }


        return User::Create([
            'provider_id' => $social_user->id,
            'name' => $social_user->name,
            'email' => $social_user->email,
            'nickname' => $social_user->nickname,
            'avatar_img' => $social_user->avatar,
            'role_id' => 1, //set role to guest
            'social_login' => true //tell the database they are logging in from oauth

        ]);

    }
}

person Magearlik    schedule 15.05.2016    source источник


Ответы (2)


Сообщение об ошибке на самом деле самоочевидно. Когда вы делаете User::where('provider_id', $social_user->id), вы получаете объект построителя, который реализует

Illuminate\Database\Eloquent\Builder.

Вы можете вызвать ->get(), чтобы получить набор результатов (набор объектов, реализующий

Illuminate\Contracts\Auth\Authenticatable

в вашем случае, чтобы вы могли перебирать их), или, как вы это делали, вы можете получить первое совпадение с ->first() (один объект, реализующий

Illuminate\Contracts\Auth\Authenticatable).

Вы можете прочитать больше в документации Eloquent.

Суть в том, что пока вы не вызовете ->get() или ->first(), вы работаете с объектом-построителем. Фактически существует также метод ->find(), который используется для получения записи по pk, вы не можете использовать его для поиска записей по ограничениям (where), но он также возвращает объект модели.

person Magearlik    schedule 16.05.2016
comment
Этот ответ был первоначально размещен здесь: stackoverflow.com/questions/37247380/ < / а> - person Magearlik; 16.05.2016

Проблема, с которой я сталкиваюсь с этим подходом, заключается в том, что если пользователь входит, скажем, из Google с адресом электронной почты [email protected], а затем входит в систему из Facebook, используя [email protected], он входит в ту же учетную запись! Право на безопасность.

На мой взгляд, это неверное предположение. Это не проблема безопасности.

OAuth используется в качестве делегирования аутентификации, если пользователь контролирует учетные записи в разных провайдерах с одним и тем же адресом электронной почты, это просто означает, что у него есть больше сторонних служб OAuth, с помощью которых можно проверить контроль своей личности (адрес электронной почты).

Я бы счел это ошибкой, если бы вы ограничили меня возможностью входа только с одним поставщиком OAuth и запретили мне использовать другого с тем же адресом электронной почты.

person Cyril Graze    schedule 14.04.2017