Heim  >  Artikel  >  Backend-Entwicklung  >  Eine kurze Diskussion über die verbindliche Gestaltung mehrerer sozialer Konten

Eine kurze Diskussion über die verbindliche Gestaltung mehrerer sozialer Konten

WBOY
WBOYOriginal
2016-09-28 08:54:131110Durchsuche

Dearmadman hat larastarscn/socialite in Laravel Socialite Detaillierte Erklärung verwendet, um das Problem der Integration von Drittanbieterkonten zu lösen. Was passiert also, nachdem die Benutzerinformationen erhalten wurden? Wie integriere ich mehrere soziale Konten? Wie verbinde ich dasselbe Konto? Lassen Sie uns in diesem Artikel die integrierte Anmeldung besprechen.

Am Anfang

Wenn wir zunächst nur ein einziges soziales Login integrieren müssen, fügen wir dem Benutzermodell möglicherweise einfach ähnliche Attribute wie open_id oder github_id hinzu, um die Aufgabe schnell abzuschließen. Dann müssen wir in der Datenbank die entsprechenden Attribute hinzufügen das Tabellenfeld. Dies ist eine schnelle und effiziente Möglichkeit, die Arbeit zu erledigen.

Aber was sollten wir tun, wenn die Anforderungen steigen und wir die Integration eines oder mehrerer sozialer Logins erfordern? Müssen wir dennoch absichtlich entsprechende Felder zur Tabellenstruktur hinzufügen?

<code class="php">Schema::table('users', function ($table) {
  $table->string('github_id');
  $table->string('douban_id');
});</code>

Dies verstößt offensichtlich gegen das Prinzip der Offenheit und Schließung. Wenn wir dies tun, ist es denkbar, dass wir jedes Mal, wenn wir ein anderes Login integrieren, eine Änderung an der Datentabellenstruktur und während des Login-Autorisierungsrückrufs vornehmen müssen Überprüfung Zu diesem Zeitpunkt muss ein Prozess zur Integration des Treiber- und Feldabfrageabgleichs hinzugefügt werden.

Was sollen wir tun?

Phantasie

Wenn man es so betrachtet, nimmt die Benutzertabelle zu viel Kapazität ein? Sollte sie ihre Energie mit der Verwaltung dieser sozialen Identifikatoren verschwenden? Wie wäre es, wenn wir SocialiteUser so einrichten, dass es speziell die Beziehung zwischen Benutzern und sozialen Konten verwaltet? Wir müssen eine leicht skalierbare Lösung entwerfen, um soziale Anmeldungen verschiedener Fahrer zu verwalten, damit wir diese Tabellenstruktur einfach entwerfen können:

<code class="php">- socialite_users
  - id
  - user_id
  - driver
  - open_id</code>

Welche Verantwortlichkeiten sollte SocialiteUser haben? Offensichtlich wird es hauptsächlich dazu verwendet, die Beziehung zwischen sozialen Anmeldekennungen und Benutzermodellen aufrechtzuerhalten. Dann sollte es über die folgenden Fähigkeiten verfügen:

  • Social-Login-Konten an Benutzermodelle binden

  • Holen Sie sich das passende Benutzermodell

Das Folgende ist eine einfache Codedemonstration:

<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>

Verwenden Sie

Beim Autorisierungs-Anmeldevorgang stimmt der Benutzer der Autorisierung zu und die Drittanbieteranwendung leitet zur Rückrufroute weiter. Auf der Rückrufroute fordert Socialite aktiv Benutzerinformationen an und ordnet die soziale Identifikations-ID des Benutzers zu ID-Attribut des User-Modells.

Dann können wir die Fahrer-ID und die entsprechende soziale ID-ID des Benutzers in der Rückrufroute verwenden, um abzugleichen, ob in der Abfragebibliothek ein gebundener Benutzer vorhanden ist. Wenn es vorhanden ist, melden Sie sich direkt mit dem übereinstimmenden Benutzer an. Wenn es nicht vorhanden ist, erstellen Sie einen Benutzer und hängen Sie diesem Benutzer soziale Kontoinformationen an. Melden Sie sich dann mit dem neu generierten Konto an.

<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>

Wenn Sie eine neue Social-Login-Integration benötigen, müssen Sie unter diesem Gesichtspunkt überhaupt keine weiteren Codeänderungen vornehmen. Konfigurieren Sie einfach den Treiber direkt.

PS: Seien Sie herzlich willkommen, sich mit dem Thema Jianshu Laravel zu befassen, und freuen Sie sich auch über die Einreichung von Artikeln zum Thema Laravel :) Wenn Sie einen besseren Designplan haben, können Sie ihn gerne diskutieren und austauschen . Wenn es Fehler gibt, kritisieren und korrigieren Sie diese bitte. Vielen Dank :)

Antwortinhalt:

Dearmadman hat larastarscn/socialite in Laravel Socialite Detaillierte Erklärung verwendet, um das Problem der Integration von Drittanbieterkonten zu lösen. Was passiert also, nachdem die Benutzerinformationen erhalten wurden? Wie integriere ich mehrere soziale Konten? Wie verbinde ich dasselbe Konto? Lassen Sie uns in diesem Artikel die integrierte Anmeldung besprechen.

Am Anfang

Wenn wir zunächst nur ein einziges soziales Login integrieren müssen, fügen wir dem Benutzermodell möglicherweise einfach ähnliche Attribute wie open_id oder github_id hinzu, um die Aufgabe schnell abzuschließen. Dann müssen wir in der Datenbank die entsprechenden Attribute hinzufügen das Tabellenfeld. Dies ist eine schnelle und effiziente Möglichkeit, die Arbeit zu erledigen.

Aber was sollten wir tun, wenn die Anforderungen steigen und wir die Integration eines oder mehrerer sozialer Logins erfordern? Müssen wir dennoch absichtlich entsprechende Felder zur Tabellenstruktur hinzufügen?

<code class="php">Schema::table('users', function ($table) {
  $table->string('github_id');
  $table->string('douban_id');
});</code>

Dies verstößt offensichtlich gegen das Prinzip der Offenheit und Schließung. Wenn wir dies tun, ist es denkbar, dass wir jedes Mal, wenn wir ein anderes Login integrieren, eine Änderung an der Datentabellenstruktur und während des Login-Autorisierungsrückrufs vornehmen müssen Überprüfung Gleichzeitig muss ein Prozess zur Integration des Treiber- und Feldabfrageabgleichs hinzugefügt werden.

Was sollen wir tun?

Phantasie

Wenn man es so betrachtet, nimmt die Benutzertabelle zu viel Kapazität ein? Sollte sie ihre Energie mit der Verwaltung dieser sozialen Identifikatoren verschwenden? Wie wäre es, wenn wir SocialiteUser so einrichten, dass es speziell die Beziehung zwischen Benutzern und sozialen Konten verwaltet? Wir müssen eine leicht skalierbare Lösung entwerfen, um soziale Anmeldungen verschiedener Fahrer zu verwalten, damit wir diese Tabellenstruktur einfach entwerfen können:

<code class="php">- socialite_users
  - id
  - user_id
  - driver
  - open_id</code>

Welche Verantwortlichkeiten sollte SocialiteUser haben? Offensichtlich wird es hauptsächlich dazu verwendet, die Beziehung zwischen sozialen Anmeldekennungen und Benutzermodellen aufrechtzuerhalten. Dann sollte es über die folgenden Fähigkeiten verfügen:

  • 将社交登录账户绑定到用户模型上

  • 获取匹配的用户模型

以下为简单的代码演示:

<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 相关文章的投稿 :),作者知识技能水平有限,如果你有更好的设计方案欢迎讨论交流,如果有错误的地方也请批评指正,在此表示感谢谢谢 :)

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn