Dearmadman은 타사 계정 로그인 통합 문제를 해결하기 위해 Laravel Socialite 상세 설명에서 larastarscn/socialite를 사용했습니다. 그러면 사용자 정보를 얻은 후에는 어떻게 되나요? 여러 소셜 계정을 통합하는 방법은 무엇입니까? 이번 글에서는 통합 로그인에 대해 알아보겠습니다.
처음에는 단일 소셜 로그인만 통합해야 하는 경우 작업을 빠르게 완료하기 위해 사용자 모델에 open_id 또는 github_id 유사한 속성을 추가하기만 하면 됩니다. 그런 다음 데이터베이스에 해당 속성을 추가해야 합니다. 테이블. 이는 작업을 완료하는 빠르고 효율적인 방법입니다.
그러나 하나 이상의 소셜 로그인을 통합해야 하는 요구가 더 많아지면 어떻게 해야 합니까? 의도적으로 테이블 구조에 해당 필드를 추가해야 합니까?
<code class="php">Schema::table('users', function ($table) { $table->string('github_id'); $table->string('douban_id'); });</code>
이는 명백히 개방성과 폐쇄성의 원칙을 위반하는 것이며, 다른 로그인을 통합할 때마다 로그인 인증 콜백 중에 데이터 테이블 구조를 수정해야 한다고 생각할 수 있습니다. 검증 이때 드라이버와 필드 쿼리 매칭을 통합하는 과정이 추가되어야 합니다.
어떻게 해야 할까요?
이렇게 생각하면 User 테이블이 너무 많은 용량을 가정하는 것인가요? 이러한 소셜 식별자를 관리하는 데 에너지를 낭비해야 할까요? SocialiteUser를 배치하여 사용자와 소셜 계정 간의 관계를 구체적으로 관리하면 어떨까요? 다양한 운전자의 소셜 로그인을 관리하기 위해 쉽게 확장 가능한 솔루션을 설계해야 하므로 다음 테이블 구조를 쉽게 설계할 수 있습니다.
<code class="php">- socialite_users - id - user_id - driver - open_id</code>
SocialiteUser는 어떤 책임을 져야 하나요? 분명히 이는 주로 소셜 로그인 식별자와 사용자 모델 간의 관계를 유지하는 데 사용됩니다. 그러면 다음과 같은 기능이 있어야 합니다.
소셜 로그인 계정을 사용자 모델에 바인딩
일치하는 사용자 모델 가져오기
다음은 간단한 코드 데모입니다.
<code class="php"><?php namespace App; use Illuminate\Database\Eloquent\Model; class SocialiteUser extends Model { public $guarded = ['id']; /** * Get user instance by driver and openid. * * @param $driver string * @param $openid string * @return /App/User|null */ public function getUser($driver, $openid) { $finder = $this->where([ 'driver' => $driver, 'open_id' => $openid ])->first(); return $finder ? $finder->user : $finder; } /** * get related user model. * * @return /App/User||null */ public function user() { return $this->belongsTo('App\User'); } /** * Save a new record. * * @param $userId integer * @param $driver string * @param $id string * @return /App/SocialiteUser */ public function saveOne($userId, $driver, $id) { return $this->create([ 'user_id' => $userId, 'driver' => $driver, 'open_id' => $id ]); } } </code>
승인 로그인 프로세스에서 사용자는 승인에 동의하며, 타사 애플리케이션은 콜백 경로로 리디렉션됩니다. 콜백 경로에서 Socialite는 사용자 정보를 얻고 사용자의 소셜 ID를 User
모델의 id 속성입니다.
그런 다음 콜백 경로에서 운전자 ID와 사용자의 해당 소셜 ID ID를 사용하여 쿼리 라이브러리에 바인딩된 사용자가 있는지 여부를 일치시킬 수 있습니다. 존재하는 경우 일치하는 사용자로 직접 로그인하십시오. 존재하지 않는 경우 사용자를 생성하고 이 사용자에게 소셜 계정 정보를 첨부하십시오. 그런 다음 새로 생성된 계정을 사용하여 로그인합니다.
<code class="php"><?php namespace App\Http\Controllers; use App\SocialiteUser; use App\User; use Socialite; class OAuthAuthorizationController extends Controller { // public function redirectToProvider($driver) { return Socialite::driver($driver)->redirect(); } public function handleProviderCallback($driver) { $user = Socialite::driver($driver)->user(); $model = new User(); $socialiteUser = new SocialiteUser(); $finder = $socialiteUser->getUser($driver, $user->id); if (! $finder) { $finder = $model->generateUserInstance(); $finder->save(); $socialiteUser->saveOne($finder->id, $driver, $user->id); } Auth::login($finder); return view('home'); } } </code>
이러한 관점에서 새로운 소셜 로그인 통합이 필요한 경우 다른 코드를 변경할 필요가 전혀 없으며 드라이버를 직접 구성하면 됩니다.
PS: Jianshu Laravel 주제에 관심을 가져주신 것을 환영하며, Laravel 관련 기사의 제출도 환영합니다. :) 작성자의 지식과 기술이 제한되어 있으면 더 나은 디자인 계획이 있으면 토론하고 교환할 수 있습니다. . 틀린 부분이 있으면 비판해 주시고 정정해 주시면 감사하겠습니다 :)
Dearmadman은 타사 계정 로그인 통합 문제를 해결하기 위해 Laravel Socialite 상세 설명에서 larastarscn/socialite를 사용했습니다. 그러면 사용자 정보를 얻은 후에는 어떻게 되나요? 여러 소셜 계정을 통합하는 방법은 무엇입니까? 이번 글에서는 통합 로그인에 대해 알아보겠습니다.
처음에는 단일 소셜 로그인만 통합해야 하는 경우 작업을 빠르게 완료하기 위해 사용자 모델에 open_id 또는 github_id 유사한 속성을 추가하기만 하면 됩니다. 그런 다음 데이터베이스에 해당 속성을 추가해야 합니다. 테이블. 이는 작업을 완료하는 빠르고 효율적인 방법입니다.
그러나 하나 이상의 소셜 로그인을 통합해야 하는 요구가 더 많아지면 어떻게 해야 합니까? 의도적으로 테이블 구조에 해당 필드를 추가해야 합니까?
<code class="php">Schema::table('users', function ($table) { $table->string('github_id'); $table->string('douban_id'); });</code>
이는 명백히 개방성과 폐쇄성의 원칙을 위반하는 것입니다. 이렇게 하면 다른 로그인을 통합할 때마다 로그인 인증 콜백 확인 중에 데이터 테이블 구조를 수정해야 한다고 생각할 수 있습니다. 동시에 드라이버와 필드 쿼리 매칭을 통합하는 프로세스가 추가되어야 합니다.
어떻게 해야 할까요?
이렇게 생각해보면 User 테이블이 너무 많은 용량을 가정하는 것일까요? 이러한 소셜 식별자를 관리하는 데 에너지를 낭비해야 할까요? SocialiteUser를 배치하여 사용자와 소셜 계정 간의 관계를 구체적으로 관리하면 어떨까요? 다양한 운전자의 소셜 로그인을 관리하기 위해 쉽게 확장 가능한 솔루션을 설계해야 하므로 다음 테이블 구조를 쉽게 설계할 수 있습니다.
<code class="php">- socialite_users - id - user_id - driver - open_id</code>
SocialiteUser는 어떤 책임을 져야 하나요? 분명히 이는 주로 소셜 로그인 식별자와 사용자 모델 간의 관계를 유지하는 데 사용됩니다. 그러면 다음과 같은 기능이 있어야 합니다.
将社交登录账户绑定到用户模型上
获取匹配的用户模型
以下为简单的代码演示:
<code class="php"><?php namespace App; use Illuminate\Database\Eloquent\Model; class SocialiteUser extends Model { public $guarded = ['id']; /** * Get user instance by driver and openid. * * @param $driver string * @param $openid string * @return /App/User|null */ public function getUser($driver, $openid) { $finder = $this->where([ 'driver' => $driver, 'open_id' => $openid ])->first(); return $finder ? $finder->user : $finder; } /** * get related user model. * * @return /App/User||null */ public function user() { return $this->belongsTo('App\User'); } /** * Save a new record. * * @param $userId integer * @param $driver string * @param $id string * @return /App/SocialiteUser */ public function saveOne($userId, $driver, $id) { return $this->create([ 'user_id' => $userId, 'driver' => $driver, 'open_id' => $id ]); } } </code>
在授权登录流程中,用户同意授权,第三方应用将重定向到回调路由,回调路由中 Socialite 会主动请求获取用户资料,并将用户的社交标识 ID 映射到 User
模型的 id 属性上。
那么我们就可以在回调路由中根据驱动标识和用户相应的社交标识 ID 来匹配查询库中是否已存在绑定的用户。如果存在那就直接使用匹配到的用户登录,如果不存在,那么就生成一个用户,并为这个用户附加社交账户信息。然后使用新生成的账户登录。
<code class="php"><?php namespace App\Http\Controllers; use App\SocialiteUser; use App\User; use Socialite; class OAuthAuthorizationController extends Controller { // public function redirectToProvider($driver) { return Socialite::driver($driver)->redirect(); } public function handleProviderCallback($driver) { $user = Socialite::driver($driver)->user(); $model = new User(); $socialiteUser = new SocialiteUser(); $finder = $socialiteUser->getUser($driver, $user->id); if (! $finder) { $finder = $model->generateUserInstance(); $finder->save(); $socialiteUser->saveOne($finder->id, $driver, $user->id); } Auth::login($finder); return view('home'); } } </code>
这样看来,如果需求一种新的社交登录的集成,那么完全不需要做出其它代码的改动,直接配置驱动就可以了。
PS: 欢迎关注简书 Laravel 专题,也欢迎 Laravel 相关文章的投稿 :),作者知识技能水平有限,如果你有更好的设计方案欢迎讨论交流,如果有错误的地方也请批评指正,在此表示感谢谢谢 :)