Laravel5.1 實現第三方登入認證(包括微博、QQ、微信、豆瓣)
第三方登入認證能簡化使用者登入/註冊的操作,降低使用者登入/註冊的門檻,對提高應用的使用者轉化率很有幫助。
Socialite
Laravel 為我們提供了簡單、易用的方式,使用 Laravel Socialite 進行 OAuth(OAuth1 和 OAuth2 都有支援) 認證。
SocialiteProviders
SocialiteProviders 通過擴充套件 Socialite 的 Driver,實現了很多第三方認證。國內的有:微博、QQ、微信、豆瓣。當然你自己也可以參照實現其他的,只要那個網站支援 OAuth。
SocialiteProviders 的使用也超級簡單易用,每個都對應了文件。其實,不懂英文也能看懂。
文件地址:
其實,文章到這裡就應該結束了。由於文件是基於 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_KEY
和 WEIBO_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]
。注意大小寫。
最後:
如有錯誤,還望指正。