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

jopen 9年前發布 | 80K 次閱讀 Laravel Web框架

前言

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

Socialite

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

Socialite 目前支持的認證有 非死book、推ter、Google、LinkedIn、GitHub、Bitbucket。(恩,有一半是“不存在”的網站。)

Socialite 的用法官方文檔中已經講得很詳細了,恕不贅述。

英文好的同學,建議直接看 Laravel 官方文檔, 畢竟看二手知識是有高風險的

英文不好的同學(比如我),下面是中文文檔:

Laravel 5.0: http://laravel-china.org/docs/5.0/authentication#social-authentication

Laravel 5.1: http://laravel.tw/docs/5.1/authentication#social-authentication

</div>

SocialiteProviders

SocialiteProviders 通過擴展 Socialite 的 Driver,實現了很多第三方認證。國內的有:微博、QQ、微信、豆瓣。當然你自己也可以參照實現其他的,只要那個網站支持 OAuth。

SocialiteProviders 的使用也超級簡單易用,每個都對應了文檔。其實,不懂英文也能看懂。

文檔地址: http://socialiteproviders.github.io/

其實,文章到這里就應該結束了。由于文檔是基于 Laravel5.0 的,所以我還是打算基于 Laravel5.1 演示一遍,并說一下要注意的地方吧。

</div>

以 Weibo 為例

1.安裝

composer require socialiteproviders/weibo

2.添加 Service Provider

如果之前添加過 Socialite Provider,得先注釋掉:

文件config/app.php

</div>

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

3.添加 Facades Aliase

如果之前安裝 Socialite 時添加過,就不需要再添加了。

還是文件config/app.php

</div>

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

4.添加事件處理器

文件app/Providers/EventServiceProvider.php

protected $listen = [
    'SocialiteProviders\Manager\SocialiteWasCalled' => [
        'SocialiteProviders\Weibo\WeiboExtendSocialite@handle',
    ],
];

這里順便提一下 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);
}

}</pre>

它只是在啟動時會觸發SocialiteWasCalled事件,剛才在SocialiteProviders\Manager\SocialiteWasCalled事件的監聽器中加上了事件處理器:SocialiteProviders\Weibo\WeiboExtendSocialite@handle。處理器的源碼:

<?php

namespace SocialiteProviders\Weibo;

use SocialiteProviders\Manager\SocialiteWasCalled;

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

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

5.添加路由

文件app/Http/routes.php

// 引導用戶到新浪微博的登錄授權頁面
Route::get('auth/weibo', 'Auth\AuthController@weibo');
// 用戶授權后新浪微博回調的頁面
Route::get('auth/callback', 'Auth\AuthController@callback');

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_KEY和WEIBO_SECRET的具體值,這個是由新浪微博分發給你的,在新浪微博的 授權回調頁 中填寫WEIBO_REDIRECT_URI。這些細節已經超出本文的內容,建議直接到 http://open.weibo.com 查閱新浪微博的手冊。

</div>

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();
}

當然,并不是有了這些方法就一定能獲取到你需要的數據的。比如,在新浪的接口中,想要獲取用戶的 email 是得用戶授權的,得到授權后請求獲取郵箱的接口,才能拿到用戶的郵箱。

詳情參見:

http://open.weibo.com/wiki/Scope

http://open.weibo.com/wiki/2/account/profile/email </div>

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

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

補充:

http://socialiteproviders.github.io/providers/qq/ 文檔中有一處錯誤。

SocialiteProviders\QQ\QqExtendSocialite@handle應該改為:SocialiteProviders\Qq\QqExtendSocialite@handle。 注意大小寫

</div>

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

原文 http://segmentfault.com/a/1190000003103229

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!