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

前言

第三方登陸認證能簡化用戶登陸/註冊的操做,下降用戶登陸/註冊的門檻,對提升應用的用戶轉化率頗有幫助。php

Socialite

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

Socialite 目前支持的認證有 Facebook、Twitter、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-authenticationgit

SocialiteProviders

SocialiteProviders 經過擴展 Socialite 的 Driver,實現了不少第三方認證。國內的有:微博、QQ、微信、豆瓣。固然你本身也能夠參照實現其餘的,只要那個網站支持 OAuth。
SocialiteProviders 的使用也超級簡單易用,每一個都對應了文檔。其實,不懂英文也能看懂。
文檔地址:http://socialiteproviders.github.io/
其實,文章到這裏就應該結束了。因爲文檔是基於 Laravel5.0 的,因此我仍是打算基於 Laravel5.1 演示一遍,並說一下要注意的地方吧。github

以 Weibo 爲例

1.安裝

composer require socialiteproviders/weibo

2.添加 Service Provider

若是以前添加過 Socialite Provider,得先註釋掉:
文件 config/app.phpshell

'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.phpapp

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

這裏順便提一下 SocialiteProviders 的原理。composer

SocialiteProviders\Manager\ServiceProvider 其實是繼承於 Laravel\Socialite\SocialiteServiceProvider 的,這是它的源碼:ide

<?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\WeiboExtendSocialite@handle。處理器的源碼:測試

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

固然,並非有了這些方法就必定能獲取到你須要的數據的。好比,在新浪的接口中,想要獲取用戶的 email 是得用戶受權的,獲得受權後請求獲取郵箱的接口,才能拿到用戶的郵箱。
詳情參見:
http://open.weibo.com/wiki/Scope
http://open.weibo.com/wiki/2/account/profile/email

可是,id 這個應該是全部第三方認證服務提供商都會返回的。否則那就沒有辦法做帳號關聯了。

獲取到第三方的 id 後,若是這個 id 和你網站用戶帳號有綁定,就直接登陸你網站用戶的帳號。若是沒有任何帳號與之綁定,就應該提示用戶綁定已有帳號或者是註冊新帳號什麼的,這些具體邏輯就不在多說了。還有,在新浪上面還有一個取消受權回調頁的值須要填,是用戶在受權頁點擊「取消」按鈕時新浪回調的頁面。這個能夠設置爲你網站的登陸頁面或者其餘頁面。

補充:
http://socialiteproviders.github.io/providers/qq/ 文檔中有一處錯誤。
SocialiteProviders\QQ\QqExtendSocialite@handle 應該改成:SocialiteProviders\Qq\QqExtendSocialite@handle注意大小寫

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

相關文章
相關標籤/搜索