Laravel 社交名流 - 不同的提供商使用相同的电子邮件 - 安全性如何修复
Laravel Socialite - Different Providers With Same Email - Security How to Fix
好的,所以我阅读了如何在我的应用程序中实现 Laravel 社交名流,这样我就可以让用户使用 Google 或 Facebook 登录。我阅读了如何操作 here。我在使用这种方法时遇到的问题是,如果用户使用电子邮件 myemail@example.com 从 say Google 登录,然后使用 myemail@example.com 从 Facebook 登录,他们将登录同一个帐户!安全问题对。所以我想在我让他们登录之前我会检查你可以获得的提供商 ID,但是当我尝试比较他们创建帐户时我存储在数据库中的 provider_id 与 provider_id 存储在社交名流用户变量中我得到这个错误:
传递给 Illuminate\Auth\SessionGuard::login() 的参数 1 必须实现接口 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
]);
}
}
错误消息实际上是自我解释的。
当您执行 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
),但它也是returns模型对象。
The problem I encounter with this approach is that if a user logs in
from say Google with email myemail@example.com then logs in from
Facebook using myemail@example.com they are logging into the same
account! Security issue right.
在我看来,这是一个错误的假设。这不是安全问题。
OAuth 用作身份验证委托,如果用户使用同一电子邮件控制不同提供商的帐户,这仅意味着他有更多的第 3 方 OAuth 服务来验证对其身份的控制(电子邮件)
如果您限制我只能使用一个 OAuth 提供商登录,并禁止我使用同一电子邮件地址使用另一个提供商,我会认为这是一个错误。
好的,所以我阅读了如何在我的应用程序中实现 Laravel 社交名流,这样我就可以让用户使用 Google 或 Facebook 登录。我阅读了如何操作 here。我在使用这种方法时遇到的问题是,如果用户使用电子邮件 myemail@example.com 从 say Google 登录,然后使用 myemail@example.com 从 Facebook 登录,他们将登录同一个帐户!安全问题对。所以我想在我让他们登录之前我会检查你可以获得的提供商 ID,但是当我尝试比较他们创建帐户时我存储在数据库中的 provider_id 与 provider_id 存储在社交名流用户变量中我得到这个错误:
传递给 Illuminate\Auth\SessionGuard::login() 的参数 1 必须实现接口 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
]);
}
}
错误消息实际上是自我解释的。
当您执行 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
),但它也是returns模型对象。
The problem I encounter with this approach is that if a user logs in from say Google with email myemail@example.com then logs in from Facebook using myemail@example.com they are logging into the same account! Security issue right.
在我看来,这是一个错误的假设。这不是安全问题。
OAuth 用作身份验证委托,如果用户使用同一电子邮件控制不同提供商的帐户,这仅意味着他有更多的第 3 方 OAuth 服务来验证对其身份的控制(电子邮件)
如果您限制我只能使用一个 OAuth 提供商登录,并禁止我使用同一电子邮件地址使用另一个提供商,我会认为这是一个错误。