增加社会化登录
This commit is contained in:
170
extend/socialite/src/provider/AbstractProvider.php
Normal file
170
extend/socialite/src/provider/AbstractProvider.php
Normal file
@@ -0,0 +1,170 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Administrator
|
||||
* Date: 2018/12/28
|
||||
* Time: 11:50
|
||||
*/
|
||||
namespace thinking\socialite\provider;
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
use think\exception\HttpException;
|
||||
use think\exception\HttpResponseException;
|
||||
use think\facade\Session;
|
||||
use GuzzleHttp\ClientInterface;
|
||||
|
||||
class AbstractProvider
|
||||
{
|
||||
// 应用ID
|
||||
protected $appId;
|
||||
// 应用秘钥
|
||||
protected $appSecret;
|
||||
// 回调地址
|
||||
protected $redirectUrl;
|
||||
// scope
|
||||
protected $scope;
|
||||
// http 客户端
|
||||
protected $httpClient = null;
|
||||
// request
|
||||
protected $request;
|
||||
|
||||
protected $clientIdKey = 'client_id';
|
||||
|
||||
public function __construct($appId = '', $appSecret='', $redirectUrl='', $scope = '')
|
||||
{
|
||||
$this->appId = $appId;
|
||||
$this->appSecret = $appSecret;
|
||||
$this->redirectUrl = $redirectUrl;
|
||||
$this->scope = $scope;
|
||||
$this->request = app('request');
|
||||
}
|
||||
|
||||
protected function getHttpClient()
|
||||
{
|
||||
if (is_null($this->httpClient)) {
|
||||
$this->httpClient = new Client();
|
||||
}
|
||||
return $this->httpClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* oauth login
|
||||
*
|
||||
* @time at 2018年12月29日
|
||||
* @return void
|
||||
*/
|
||||
public function oauth()
|
||||
{
|
||||
if (!$this->request->get('code')) {
|
||||
throw new HttpResponseException(redirect($this->authorizeUrl . '?' . http_build_query($this->createOauthParams())));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* create oauth params
|
||||
*
|
||||
* @time at 2018年12月29日
|
||||
* @return array
|
||||
*/
|
||||
protected function createOauthParams()
|
||||
{
|
||||
return [
|
||||
'response_type' => 'code',
|
||||
$this->clientIdKey => $this->appId,
|
||||
'redirect_uri' => $this->redirectUrl,
|
||||
'scope' => $this->getScope(),
|
||||
'state' => $this->state(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* set scope
|
||||
*
|
||||
* @time at 2018年12月29日
|
||||
* @param $scope
|
||||
* @return $this
|
||||
*/
|
||||
public function setScope($scope)
|
||||
{
|
||||
$this->scope = $scope;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* get scope
|
||||
*
|
||||
* @time at 2018年12月29日
|
||||
* @return string
|
||||
*/
|
||||
protected function getScope()
|
||||
{
|
||||
return is_array($this->scope) ? trim(implode($this->scope), ',') : $this->scope;
|
||||
}
|
||||
|
||||
/**
|
||||
* get state
|
||||
*
|
||||
* @time at 2018年12月29日
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getState()
|
||||
{
|
||||
$state = $this->request->session('state');
|
||||
|
||||
$this->request->session('state', null);
|
||||
|
||||
return $state;
|
||||
}
|
||||
|
||||
/**
|
||||
* check state
|
||||
*
|
||||
* @time at 2018年12月29日
|
||||
* @return void
|
||||
*/
|
||||
protected function checkState()
|
||||
{
|
||||
if ($this->request->param('state') != $this->getState()) {
|
||||
throw new HttpException(401, 'Authorized login State verification failed, Please check it');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* generate state
|
||||
*
|
||||
* @time at 2018年12月29日
|
||||
* @return string
|
||||
*/
|
||||
protected function state()
|
||||
{
|
||||
$state = md5(rand(1,100000));
|
||||
|
||||
Session::set('state', $state);
|
||||
|
||||
return $state;
|
||||
}
|
||||
|
||||
/**
|
||||
* get token params
|
||||
*
|
||||
* @time at 2018年12月29日
|
||||
* @return array
|
||||
*/
|
||||
protected function getTokenParams()
|
||||
{
|
||||
$this->checkState();
|
||||
|
||||
return [
|
||||
'code' => $this->request->get('code'),
|
||||
'client_secret' => $this->appSecret,
|
||||
$this->clientIdKey => $this->appId,
|
||||
'redirect_uri' => $this->redirectUrl,
|
||||
];
|
||||
}
|
||||
|
||||
protected function getPostKey()
|
||||
{
|
||||
return (version_compare(ClientInterface::VERSION, '6') === 1) ? 'form_params' : 'body';
|
||||
}
|
||||
}
|
68
extend/socialite/src/provider/GithubProvider.php
Normal file
68
extend/socialite/src/provider/GithubProvider.php
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Administrator
|
||||
* Date: 2018/12/28
|
||||
* Time: 11:18
|
||||
*/
|
||||
namespace thinking\socialite\provider;
|
||||
|
||||
use think\exception\HttpException;
|
||||
use thinking\socialite\User;
|
||||
|
||||
class GithubProvider extends AbstractProvider
|
||||
{
|
||||
protected $authorizeUrl = 'https://github.com/login/oauth/authorize';
|
||||
|
||||
protected $accessTokenUrl = 'https://github.com/login/oauth/access_token';
|
||||
|
||||
protected $userUrl = 'https://api.github.com/user';
|
||||
|
||||
/**
|
||||
* 获取 Access Token
|
||||
*
|
||||
* @time at 2018年12月28日
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getAccessToken()
|
||||
{
|
||||
$response = $this->getHttpClient()->post($this->accessTokenUrl, [
|
||||
'verify' => false,
|
||||
'headers' => ['Accept' => 'application/json'],
|
||||
$this->getPostKey() => array_merge($this->getTokenParams())
|
||||
]);
|
||||
|
||||
$token = json_decode($response->getBody()->getContents(), true);
|
||||
|
||||
if (!isset($token['access_token'])) {
|
||||
throw new HttpException(401, 'Access Token Missing, Please ReLogin');
|
||||
}
|
||||
|
||||
return $token['access_token'];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取用户信息
|
||||
*
|
||||
* @time at 2018年12月28日
|
||||
* @return mixed
|
||||
*/
|
||||
public function user()
|
||||
{
|
||||
$response = $this->getHttpClient()->get($this->userUrl,[
|
||||
'verify' => false,
|
||||
'headers' => ['Authorization' => sprintf('token %s', $this->getAccessToken())]
|
||||
]);
|
||||
|
||||
$user = json_decode($response->getBody(), true);
|
||||
|
||||
return (new User)->setUser($user)->map([
|
||||
'id' => $user['id'],
|
||||
'nickname' => $user['login'],
|
||||
'name' => $user['name'],
|
||||
'email' => $user['email'],
|
||||
'avatar' => $user['avatar_url'],
|
||||
]);
|
||||
}
|
||||
}
|
100
extend/socialite/src/provider/QqProvider.php
Normal file
100
extend/socialite/src/provider/QqProvider.php
Normal file
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Administrator
|
||||
* Date: 2018/12/28
|
||||
* Time: 11:18
|
||||
*/
|
||||
namespace thinking\socialite\provider;
|
||||
|
||||
use think\exception\HttpException;
|
||||
use thinking\socialite\contract\Provider;
|
||||
use thinking\socialite\User;
|
||||
|
||||
class QqProvider extends AbstractProvider implements Provider
|
||||
{
|
||||
protected $authorizeUrl = 'https://graph.qq.com/oauth2.0/authorize';
|
||||
|
||||
protected $accessTokenUrl = 'https://graph.qq.com/oauth2.0/token';
|
||||
|
||||
protected $openIdUrl = 'https://graph.qq.com/oauth2.0/me';
|
||||
|
||||
protected $userUrl = 'https://graph.qq.com/user/get_user_info';
|
||||
|
||||
|
||||
/**
|
||||
* 获取 Access Token
|
||||
*
|
||||
* @time at 2018年12月28日
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getAccessToken()
|
||||
{
|
||||
|
||||
$response = $this->getHttpClient()->get($this->accessTokenUrl, [
|
||||
'verify' => false,
|
||||
'query' => array_merge($this->getTokenParams(), ['grant_type' => 'authorization_code'])
|
||||
]);
|
||||
|
||||
parse_str($response->getBody()->getContents(), $token);
|
||||
|
||||
if (!isset($token['access_token'])) {
|
||||
throw new HttpException(401, 'Access Token Missing, Please ReLogin');
|
||||
}
|
||||
return $token['access_token'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 Open ID
|
||||
*
|
||||
* @time at 2018年12月28日
|
||||
* @return array
|
||||
*/
|
||||
protected function getOpenId()
|
||||
{
|
||||
$accessToken = $this->getAccessToken();
|
||||
|
||||
$response = $this->getHttpClient()->get($this->openIdUrl, [
|
||||
'verify' => false,
|
||||
'query' => ['access_token' => $accessToken]
|
||||
]);
|
||||
|
||||
$openidStr = (string)$response->getBody()->getContents();
|
||||
|
||||
$openIdArr = json_decode(substr($openidStr,strpos($openidStr,'(')+1,-3),true);
|
||||
|
||||
return array_merge($openIdArr, ['access_token' => $accessToken]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户信息
|
||||
*
|
||||
* @time at 2018年12月28日
|
||||
* @return mixed
|
||||
*/
|
||||
public function user()
|
||||
{
|
||||
$getUserParams = $this->getOpenId();
|
||||
|
||||
unset($getUserParams['app_id']);
|
||||
$getUserParams['oauth_consumer_key'] = $this->appId;
|
||||
|
||||
$response = $this->getHttpClient()->get($this->userUrl, [
|
||||
'verify' => false,
|
||||
'headers' => ['Accept' => 'application/json'],
|
||||
'query' => $getUserParams,
|
||||
]);
|
||||
|
||||
$user = json_decode($response->getBody()->getContents(), true);
|
||||
|
||||
$user['open_id'] = $getUserParams['openid'];
|
||||
|
||||
return (new User)->setUser($user)->map([
|
||||
'id' => $getUserParams['openid'],
|
||||
'nickname' => $user['nickname'],
|
||||
'avatar' => $user['figureurl_2'],
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
}
|
87
extend/socialite/src/provider/WeiBoProvider.php
Normal file
87
extend/socialite/src/provider/WeiBoProvider.php
Normal file
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Administrator
|
||||
* Date: 2018/12/28
|
||||
* Time: 11:18
|
||||
*/
|
||||
namespace thinking\socialite\provider;
|
||||
|
||||
use think\exception\HttpException;
|
||||
use thinking\socialite\User;
|
||||
|
||||
class WeiBoProvider extends AbstractProvider
|
||||
{
|
||||
protected $authorizeUrl = 'https://api.weibo.com/oauth2/authorize';
|
||||
|
||||
protected $accessTokenUrl = 'https://api.weibo.com/oauth2/access_token';
|
||||
|
||||
protected $tokenInfoUrl = 'https://api.weibo.com/oauth2/get_token_info';
|
||||
|
||||
protected $userUrl = 'https://api.weibo.com/2/users/show.json';
|
||||
|
||||
/**
|
||||
* 获取 Access Token
|
||||
*
|
||||
* @time at 2018年12月28日
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getAccessToken()
|
||||
{
|
||||
|
||||
$response = $this->getHttpClient()->post($this->accessTokenUrl, [
|
||||
'verify' => false,
|
||||
$this->getPostKey() => array_merge($this->getTokenParams(), ['grant_type' => 'authorization_code'])
|
||||
]);
|
||||
|
||||
$token = json_decode($response->getBody()->getContents(), true);
|
||||
|
||||
if (!isset($token['access_token'])) {
|
||||
throw new HttpException(401, 'Access Token Missing, Please ReLogin');
|
||||
}
|
||||
|
||||
return $token['access_token'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 Open ID
|
||||
*
|
||||
* @time at 2018年12月28日
|
||||
* @return array
|
||||
*/
|
||||
protected function getTokenInfo()
|
||||
{
|
||||
$accessToken = $this->getAccessToken();
|
||||
|
||||
$response = $this->getHttpClient()->post($this->tokenInfoUrl, [
|
||||
'verify' => false,
|
||||
$this->getPostKey() => ['access_token' => $accessToken]
|
||||
]);
|
||||
|
||||
$tokenInfo = json_decode($response->getBody()->getContents(), true);
|
||||
|
||||
return ['access_token' => $accessToken, 'uid' => $tokenInfo['uid']];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户信息
|
||||
*
|
||||
* @time at 2018年12月28日
|
||||
* @return mixed
|
||||
*/
|
||||
public function user()
|
||||
{
|
||||
$response = $this->getHttpClient()->get($this->userUrl,[
|
||||
'verify' => false,
|
||||
'query' => $this->getTokenInfo(),
|
||||
]);
|
||||
|
||||
$user = json_decode($response->getBody(), true);
|
||||
|
||||
return (new User)->setUser($user)->map([
|
||||
'id' => $user['idstr'],
|
||||
'nickname' => $user['name'],
|
||||
'avatar' => $user['profile_image_url'],
|
||||
]);
|
||||
}
|
||||
}
|
101
extend/socialite/src/provider/WxProvider.php
Normal file
101
extend/socialite/src/provider/WxProvider.php
Normal file
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Administrator
|
||||
* Date: 2018/12/28
|
||||
* Time: 11:18
|
||||
*/
|
||||
namespace thinking\socialite\provider;
|
||||
|
||||
use think\exception\HttpException;
|
||||
use thinking\socialite\contract\Provider;
|
||||
use thinking\socialite\User;
|
||||
|
||||
class WxProvider extends AbstractProvider implements Provider
|
||||
{
|
||||
protected $authorizeUrl = 'https://open.weixin.qq.com/connect/qrconnect';
|
||||
|
||||
protected $accessTokenUrl = 'https://api.weixin.qq.com/sns/oauth2/access_token';
|
||||
|
||||
protected $openIdUrl = 'https://graph.qq.com/oauth2.0/me';
|
||||
|
||||
protected $userUrl = 'https://api.weixin.qq.com/sns/userinfo';
|
||||
|
||||
protected $clientIdKey = 'appid';
|
||||
|
||||
/**
|
||||
* 获取 Access Token
|
||||
*
|
||||
* @time at 2018年12月28日
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getAccessToken()
|
||||
{
|
||||
|
||||
$response = $this->getHttpClient()->get($this->accessTokenUrl, [
|
||||
'verify' => false,
|
||||
'query' => array_merge($this->getTokenParams(), ['grant_type' => 'authorization_code'])
|
||||
]);
|
||||
|
||||
parse_str($response->getBody()->getContents(), $token);
|
||||
|
||||
if (!isset($token['access_token'])) {
|
||||
throw new HttpException(401, 'Access Token Missing, Please ReLogin');
|
||||
}
|
||||
return $token['access_token'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 Open ID
|
||||
*
|
||||
* @time at 2018年12月28日
|
||||
* @return array
|
||||
*/
|
||||
protected function getOpenId()
|
||||
{
|
||||
$accessToken = $this->getAccessToken();
|
||||
|
||||
$response = $this->getHttpClient()->get($this->openIdUrl, [
|
||||
'verify' => false,
|
||||
'query' => ['access_token' => $accessToken]
|
||||
]);
|
||||
|
||||
$openidStr = (string)$response->getBody()->getContents();
|
||||
|
||||
$openIdArr = json_decode(substr($openidStr,strpos($openidStr,'(')+1,-3),true);
|
||||
|
||||
return array_merge($openIdArr, ['access_token' => $accessToken]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户信息
|
||||
*
|
||||
* @time at 2018年12月28日
|
||||
* @return mixed
|
||||
*/
|
||||
public function user()
|
||||
{
|
||||
$getUserParams = $this->getOpenId();
|
||||
|
||||
unset($getUserParams['app_id']);
|
||||
$getUserParams['oauth_consumer_key'] = $this->appId;
|
||||
|
||||
$response = $this->getHttpClient()->get($this->userUrl, [
|
||||
'verify' => false,
|
||||
'headers' => ['Accept' => 'application/json'],
|
||||
'query' => $getUserParams,
|
||||
]);
|
||||
|
||||
$user = json_decode($response->getBody()->getContents(), true);
|
||||
|
||||
$user['open_id'] = $getUserParams['openid'];
|
||||
|
||||
return (new User)->setUser($user)->map([
|
||||
'id' => $getUserParams['openid'],
|
||||
'nickname' => $user['nickname'],
|
||||
'avatar' => $user['figureurl_2'],
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user