Laravel Socialite provides an expressive, fluent interface to OAuth authentication with Facebook, Twitter, Google, LinkedIn, GitHub and Bitbucket. It handles almost all of the boilerplate social authentication code you are dreading writing.php
Laravel Socialite 爲第三方應用的 OAuth 認證提供了很是豐富友好的接口,咱們使用它能夠很是方便快捷的對相似微信、微博等第三方登陸進行集成。laravel
OAuth(開放受權)是一個開放標準,容許用戶讓第三方應用訪問該用戶在某一網站上存儲的私密的資源(如照片,視頻,聯繫人列表),而無需將用戶名和密碼提供給第三方應用。git
OAuth 容許用戶提供一個令牌,而不是用戶名和密碼來訪問他們存放在特定服務提供者的數據。每個令牌受權一個特定的網站(例如,視頻編輯網站)在特定的時段(例如,接下來的 2 小時內)內訪問特定的資源(例如僅僅是某一相冊中的視頻)。這樣,OAuth 讓用戶能夠受權第三方網站訪問他們存儲在另外服務提供者的某些特定信息,而非全部內容。github
咱們的應用與使用 OAuth 標準的第三方應用的交互流程通常是這樣的:web
展現跳轉到第三方應用登陸的連接express
用戶點擊連接跳轉到第三方應用登陸並進行受權json
在用戶受權後第三方應用會跳轉到咱們所指定的應用回調資源地址並伴隨用於交互 AccessToken 的 Codeapi
咱們的應用拿到 Code 後自主請求第三方應用並使用 Code 獲取該用戶的 AccessToken微信
獲取 AccessToken 以後的應用便可自主的從第三方應用中獲取用戶的資源信息app
使用 Composer 進行安裝:
composer require laravel/socialite
你須要在 config/app.php
的 providers
鍵中追加:
'providers' => [ // Other service providers... Laravel\Socialite\SocialiteServiceProvider::class, ],
在 aliasses
鍵中添加 Socialite
:
'Socialite' => Laravel\Socialite\Facades\Socialite::class,
在 config/services.php
配置文件中添加驅動器配置項:
'github' => [ 'client_id' => 'your-github-app-id', 'client_secret' => 'your-github-app-secret', 'redirect' => 'http://your-callback-url', ],
至此整個流程安裝完畢。
集成微信咱們須要提供一個 WechatServiceProvider
和 一個 WechatProvider
,用這兩個文件來爲微信登陸提供驅動,Laravel Socialite 的 SocialiteManager 繼承自 Illuminate\Support\Manager
類,而其對自定義驅動提供了友好的接口支持,因此咱們能夠手動的添加一個 Wechat 驅動器:
<?php namespace Crowdfunding\Providers\Socialite; use Laravel\Socialite\Two\AbstractProvider; use Laravel\Socialite\Contracts\Provider as ProviderInterface; use Laravel\Socialite\Two\User; use GuzzleHttp\ClientInterface; class WechatProvider extends AbstractProvider implements ProviderInterface { /** * openid for get user. * @var string */ protected $openId; /** * set Open Id. * * @param string $openId */ public function setOpenId($openId) { $this->openId = $openId; return $this; } /** * {@inheritdoc}. */ protected $scopes = ['snsapi_login']; /** * {@inheritdoc}. */ public function getAuthUrl($state) { return $this->buildAuthUrlFromBase('https://open.weixin.qq.com/connect/qrconnect', $state); } /** * {@inheritdoc}. */ protected function buildAuthUrlFromBase($url, $state) { $query = http_build_query($this->getCodeFields($state), '', '&', $this->encodingType); return $url.'?'.$query.'#wechat_redirect'; } /** * {@inheritdoc}. */ protected function getCodeFields($state = null) { return [ 'appid' => $this->clientId, 'redirect_uri' => $this->redirectUrl, 'response_type' => 'code', 'scope' => $this->formatScopes($this->scopes, $this->scopeSeparator), 'state' => $state, ]; } /** * {@inheritdoc}. */ public function getTokenUrl() { return 'https://api.weixin.qq.com/sns/oauth2/access_token'; } /** * {@inheritdoc}. */ public function getUserByToken($token) { $response = $this->getHttpClient()->get('https://api.weixin.qq.com/sns/userinfo', [ 'query' => [ 'access_token' => $token, 'openid' => $this->openId, 'lang' => 'zh_CN', ], ]); return json_decode($response->getBody(), true); } /** * {@inheritdoc}. */ public function mapUserToObject(array $user) { return (new User())->setRaw($user)->map([ 'openid' => $user['openid'], 'nickname' => $user['nickname'], 'avatar' => $user['headimgurl'], 'name' => $user['nickname'], 'email' => null, 'unionid' => $user['unionid'] ]); } /** * {@inheritdoc}. */ protected function getTokenFields($code) { return [ 'appid' => $this->clientId, 'secret' => $this->clientSecret, 'code' => $code, 'grant_type' => 'authorization_code', ]; } /** * {@inheritdoc}. */ public function getAccessTokenResponse($code) { $postKey = (version_compare(ClientInterface::VERSION, '6') === 1) ? 'form_params' : 'body'; $response = $this->getHttpClient()->post($this->getTokenUrl(), [ 'headers' => ['Accept' => 'application/json'], $postKey => $this->getTokenFields($code), ]); $responseBody = json_decode($response->getBody(), true); $this->setOpenId($responseBody['openid']); return $responseBody; } }
編寫完驅動以後咱們須要註冊該驅動器到 SocialiteManager 中,所以咱們編寫一個 WechatServiceProvider:
<?php namespace Crowdfunding\Providers\Socialite; use Illuminate\Support\ServiceProvider; class WechatServiceProvider extends ServiceProvider { public function boot() { $this->app->make('Laravel\Socialite\Contracts\Factory')->extend('wechat', function ($app) { $config = $app['config']['services.wechat']; return new WechatProvider( $app['request'], $config['client_id'], $config['client_secret'], $config['redirect'] ); }); } public function register() { } }
接着咱們就能夠添加配置項及將服務提供者註冊到 Laravel 中:
// app.php 'providers' => [ // Other service providers... Crowdfunding\Providers\Socialite\WechatServiceProvider::class, ], // services.php 'wechat' => [ 'client_id' => 'appid', 'client_secret' => 'appSecret', 'redirect' => 'http://xxxxxx.proxy.qqbrowser.cc/oauth/callback/driver/wechat', ]
緊接着添加路由及控制器:
// route.php Route::group(['middleware' => 'web'], function () { Route::get('oauth/callback/driver/{driver}', 'OAuthAuthorizationController@handleProviderCallback'); Route::get('oauth/redirect/driver/{driver}', 'OauthAuthorizationController@redirectToProvider'); });
控制器:
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Http\Requests; use Socialite; class OAuthAuthorizationController extends Controller { // public function redirectToProvider($driver) { return Socialite::driver($driver)->redirect(); } public function handleProviderCallback($driver) { $user = Socialite::driver($driver)->user(); // dd($user) } }
至此集成完畢。
PS: 歡迎關注簡書 Laravel 專題,也歡迎 Laravel 相關文章的投稿 :),做者知識技能水平有限,若是你有更好的設計方案歡迎討論 :)