1. 程式人生 > >Laravel5.1 實現第三方登入認證(包括微博、QQ、微信、豆瓣)

Laravel5.1 實現第三方登入認證(包括微博、QQ、微信、豆瓣)

第三方登入認證能簡化使用者登入/註冊的操作,降低使用者登入/註冊的門檻,對提高應用的使用者轉化率很有幫助。

Socialite

Laravel 為我們提供了簡單、易用的方式,使用 Laravel Socialite 進行 OAuth(OAuth1 和 OAuth2 都有支援) 認證。

SocialiteProviders

SocialiteProviders 通過擴充套件 Socialite 的 Driver,實現了很多第三方認證。國內的有:微博、QQ、微信、豆瓣。當然你自己也可以參照實現其他的,只要那個網站支援 OAuth。
SocialiteProviders 的使用也超級簡單易用,每個都對應了文件。其實,不懂英文也能看懂。
文件地址:

http://socialiteproviders.github.io/
其實,文章到這裡就應該結束了。由於文件是基於 Laravel5.0 的,所以我還是打算基於 Laravel5.1 演示一遍,並說一下要注意的地方吧。

以 Weibo 為例

1.安裝

composer require socialiteproviders/weibo

2.新增 Service Provider

如果之前新增過 Socialite Provider,得先註釋掉:
檔案 config/app.php

'providers' => [
//    Laravel\Socialite\SocialiteServiceProvider::class,
    SocialiteProviders\Manager\ServiceProvider::class, // add
],

3.新增 Facades Aliase

如果之前安裝 Socialite 時新增過,就不需要再添加了。
還是檔案 config/app.php

'aliases' => [
    'Socialite' => Laravel\Socialite\Facades\Socialite::class, // add
],

4.新增事件處理器

檔案 app/Providers/EventServiceProvider.php

protected $listen = [
    'SocialiteProviders\Manager\SocialiteWasCalled' => [
        'SocialiteProviders\Weibo\
[email protected]
', ], ];

這裡順便提一下 SocialiteProviders 的原理。

SocialiteProviders\Manager\ServiceProvider 實際上是繼承於 Laravel\Socialite\SocialiteServiceProvider 的,這是它的原始碼:

<?php

namespace SocialiteProviders\Manager;

use Illuminate\Contracts\Events\Dispatcher;
use Laravel\Socialite\SocialiteServiceProvider;

class ServiceProvider extends SocialiteServiceProvider
{
    /**
     * @param Dispatcher         $event
     * @param SocialiteWasCalled $socialiteWasCalled
     */
    public function boot(Dispatcher $event, SocialiteWasCalled $socialiteWasCalled)
    {
        $event->fire($socialiteWasCalled);
    }
}

它只是在啟動時會觸發 SocialiteWasCalled 事件,剛才在 SocialiteProviders\Manager\SocialiteWasCalled 事件的監聽器中加上了事件處理器:SocialiteProviders\Weibo\[email protected]。處理器的原始碼:

<?php

namespace SocialiteProviders\Weibo;

use SocialiteProviders\Manager\SocialiteWasCalled;

class WeiboExtendSocialite
{
    public function handle(SocialiteWasCalled $socialiteWasCalled)
    {
        $socialiteWasCalled->extendSocialite('weibo', __NAMESPACE__.'\Provider');
    }
}

處理器做的事情就是為 Socialite 添加了一個 weibo Driver,這樣就可以使用 weibo 的 Driver 了。

5.新增路由

檔案 app/Http/routes.php

// 引導使用者到新浪微博的登入授權頁面
Route::get('auth/weibo', 'Auth\[email protected]');
// 使用者授權後新浪微博回撥的頁面
Route::get('auth/callback', 'Auth\[email protected]');

6.配置

檔案 config/services.php

'weibo' => [
    'client_id' => env('WEIBO_KEY'),
    'client_secret' => env('WEIBO_SECRET'),
    'redirect' => env('WEIBO_REDIRECT_URI'),  
],

檔案 .env

WEIBO_KEY=yourkeyfortheservice
WEIBO_SECRET=yoursecretfortheservice
WEIBO_REDIRECT_URI=http://192.168.1.7/laravel/public/auth/callback

注意:192.168.1.7 是我本地虛擬機器的地址,虛擬機器可以連外網就可以測試了。貌似 QQ 的必須繫結域名才是測試。

當然,直接將配置的具體引數寫在 config/services.php 中也是可以的,但是不推薦這樣。因為 config/services.php 屬於程式碼檔案,而 .env 屬於配置檔案。當代碼上線是隻要應用線上環境的配置檔案即可,而不需要改動程式碼檔案,這算是一個最佳實踐吧。
至於 WEIBO_KEYWEIBO_SECRET 的具體值,這個是由新浪微博分發給你的,在新浪微博的授權回撥頁中填寫 WEIBO_REDIRECT_URI。這些細節已經超出本文的內容,建議直接到 http://open.weibo.com 查閱新浪微博的手冊。

7.程式碼實現

檔案 app/Http/Controllers/Auth/AuthController.php

    public function weibo() {
        return \Socialite::with('weibo')->redirect();
        // return \Socialite::with('weibo')->scopes(array('email'))->redirect();
    }


    public function callback() {
        $oauthUser = \Socialite::with('weibo')->user();

        var_dump($oauthUser->getId());
        var_dump($oauthUser->getNickname());
        var_dump($oauthUser->getName());
        var_dump($oauthUser->getEmail());
        var_dump($oauthUser->getAvatar());
    }

訪問 http://192.168.1.7/laravel/public/auth/weibo,會跳轉到新浪微博的登入授權頁面,授權成功後,會跳轉到 http://192.168.1.7/laravel/public/auth/callback
返回的結果:

string(10) "3221174302"
string(11) "Mr_Jing1992"
NULL
NULL
string(50) "http://tp3.sinaimg.cn/3221174302/180/40064692810/1"

user 物件是現實了介面 Laravel\Socialite\Contracts\User 的,有以下幾個方法:

<?php

namespace Laravel\Socialite\Contracts;

interface User
{
    public function getId();
    public function getNickname();
    public function getName();
    public function getEmail();
    public function getAvatar();
}

但是,id 這個應該是所有第三方認證服務提供商都會返回的。不然那就沒有辦法作賬號關聯了。

獲取到第三方的 id 後,如果這個 id 和你網站使用者賬號有繫結,就直接登入你網站使用者的賬號。如果沒有任何賬號與之繫結,就應該提示使用者繫結已有賬號或者是註冊新賬號什麼的,這些具體邏輯就不在多說了。還有,在新浪上面還有一個取消授權回撥頁的值需要填,是使用者在授權頁點選“取消”按鈕時新浪回撥的頁面。這個可以設定為你網站的登入頁面或者其他頁面。

補充:
http://socialiteproviders.github.io/providers/qq/ 文件中有一處錯誤。
SocialiteProviders\QQ\[email protected] 應該改為:SocialiteProviders\Qq\[email protected]注意大小寫

最後:
如有錯誤,還望指正。