使用 Laravel\Socialite 优化第三方登录

优化callback

优化 Social ui 交互

优化第三方登录

优化第三方登录

 优化第三方登录
This commit is contained in:
Edward Yang 2022-12-21 11:15:49 +08:00
parent 85cfe3ecf5
commit 83b468907b
10 changed files with 202 additions and 254 deletions

View File

@ -16,8 +16,8 @@
"intervention/image": "^2.7",
"jenssegers/agent": "^2.6",
"laravel/framework": "^9.0",
"laravel/socialite": "^5.5",
"laravel/tinker": "^2.7",
"overtrue/socialite": "^4.5",
"spatie/laravel-permission": "^5.5",
"srmklive/paypal": "^3.0",
"stripe/stripe-php": "^8.8",

327
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "793040fbe53dc3a99b2c8ea50fcc03cb",
"content-hash": "fe94571e42db40b45b0d01fd70096a5f",
"packages": [
{
"name": "asm89/stack-cors",
@ -1970,6 +1970,81 @@
},
"time": "2022-09-08T13:45:54+00:00"
},
{
"name": "laravel/socialite",
"version": "v5.5.6",
"source": {
"type": "git",
"url": "https://github.com/laravel/socialite.git",
"reference": "1cd1682b709b8808a5b5dbb68179a58d1342aa7b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/socialite/zipball/1cd1682b709b8808a5b5dbb68179a58d1342aa7b",
"reference": "1cd1682b709b8808a5b5dbb68179a58d1342aa7b",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"ext-json": "*",
"guzzlehttp/guzzle": "^6.0|^7.0",
"illuminate/contracts": "^6.0|^7.0|^8.0|^9.0",
"illuminate/http": "^6.0|^7.0|^8.0|^9.0",
"illuminate/support": "^6.0|^7.0|^8.0|^9.0",
"league/oauth1-client": "^1.10.1",
"php": "^7.2|^8.0"
},
"require-dev": {
"mockery/mockery": "^1.0",
"orchestra/testbench": "^4.0|^5.0|^6.0|^7.0",
"phpunit/phpunit": "^8.0|^9.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "5.x-dev"
},
"laravel": {
"providers": [
"Laravel\\Socialite\\SocialiteServiceProvider"
],
"aliases": {
"Socialite": "Laravel\\Socialite\\Facades\\Socialite"
}
}
},
"autoload": {
"psr-4": {
"Laravel\\Socialite\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Taylor Otwell",
"email": "taylor@laravel.com"
}
],
"description": "Laravel wrapper around OAuth 1 & OAuth 2 libraries.",
"homepage": "https://laravel.com",
"keywords": [
"laravel",
"oauth"
],
"support": {
"issues": "https://github.com/laravel/socialite/issues",
"source": "https://github.com/laravel/socialite"
},
"time": "2022-11-08T15:07:05+00:00"
},
{
"name": "laravel/tinker",
"version": "v2.7.2",
@ -2403,6 +2478,88 @@
],
"time": "2022-04-17T13:12:02+00:00"
},
{
"name": "league/oauth1-client",
"version": "v1.10.1",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/oauth1-client.git",
"reference": "d6365b901b5c287dd41f143033315e2f777e1167"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/oauth1-client/zipball/d6365b901b5c287dd41f143033315e2f777e1167",
"reference": "d6365b901b5c287dd41f143033315e2f777e1167",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"ext-json": "*",
"ext-openssl": "*",
"guzzlehttp/guzzle": "^6.0|^7.0",
"guzzlehttp/psr7": "^1.7|^2.0",
"php": ">=7.1||>=8.0"
},
"require-dev": {
"ext-simplexml": "*",
"friendsofphp/php-cs-fixer": "^2.17",
"mockery/mockery": "^1.3.3",
"phpstan/phpstan": "^0.12.42",
"phpunit/phpunit": "^7.5||9.5"
},
"suggest": {
"ext-simplexml": "For decoding XML-based responses."
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0-dev",
"dev-develop": "2.0-dev"
}
},
"autoload": {
"psr-4": {
"League\\OAuth1\\Client\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Ben Corlett",
"email": "bencorlett@me.com",
"homepage": "http://www.webcomm.com.au",
"role": "Developer"
}
],
"description": "OAuth 1.0 Client Library",
"keywords": [
"Authentication",
"SSO",
"authorization",
"bitbucket",
"identity",
"idp",
"oauth",
"oauth1",
"single sign on",
"trello",
"tumblr",
"twitter"
],
"support": {
"issues": "https://github.com/thephpleague/oauth1-client/issues",
"source": "https://github.com/thephpleague/oauth1-client/tree/v1.10.1"
},
"time": "2022-04-15T14:02:14+00:00"
},
{
"name": "mobiledetect/mobiledetectlib",
"version": "2.8.39",
@ -3065,80 +3222,6 @@
},
"time": "2022-01-27T09:35:39+00:00"
},
{
"name": "overtrue/socialite",
"version": "4.5.0",
"source": {
"type": "git",
"url": "https://github.com/overtrue/socialite.git",
"reference": "7bbaabf4c29df3c71814f2cb3d2c2e8ab54515a1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/overtrue/socialite/zipball/7bbaabf4c29df3c71814f2cb3d2c2e8ab54515a1",
"reference": "7bbaabf4c29df3c71814f2cb3d2c2e8ab54515a1",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"ext-json": "*",
"ext-openssl": "*",
"guzzlehttp/guzzle": "^7.0",
"php": ">=8.0.2",
"symfony/http-foundation": "^6.0",
"symfony/psr-http-message-bridge": "^2.1"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^3.0",
"jetbrains/phpstorm-attributes": "^1.0",
"mockery/mockery": "^1.3",
"phpstan/phpstan": "^1.7",
"phpunit/phpunit": "^9.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Overtrue\\Socialite\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "overtrue",
"email": "anzhengchao@gmail.com"
}
],
"description": "A collection of OAuth 2 packages.",
"keywords": [
"Feishu",
"login",
"oauth",
"qcloud",
"qq",
"social",
"wechat",
"weibo"
],
"support": {
"issues": "https://github.com/overtrue/socialite/issues",
"source": "https://github.com/overtrue/socialite/tree/4.5.0"
},
"funding": [
{
"url": "https://github.com/overtrue",
"type": "github"
}
],
"time": "2022-07-08T14:28:06+00:00"
},
{
"name": "phpoption/phpoption",
"version": "1.8.1",
@ -6003,100 +6086,6 @@
],
"time": "2022-06-27T17:10:44+00:00"
},
{
"name": "symfony/psr-http-message-bridge",
"version": "v2.1.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/psr-http-message-bridge.git",
"reference": "22b37c8a3f6b5d94e9cdbd88e1270d96e2f97b34"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/22b37c8a3f6b5d94e9cdbd88e1270d96e2f97b34",
"reference": "22b37c8a3f6b5d94e9cdbd88e1270d96e2f97b34",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"php": ">=7.1",
"psr/http-message": "^1.0",
"symfony/http-foundation": "^4.4 || ^5.0 || ^6.0"
},
"require-dev": {
"nyholm/psr7": "^1.1",
"psr/log": "^1.1 || ^2 || ^3",
"symfony/browser-kit": "^4.4 || ^5.0 || ^6.0",
"symfony/config": "^4.4 || ^5.0 || ^6.0",
"symfony/event-dispatcher": "^4.4 || ^5.0 || ^6.0",
"symfony/framework-bundle": "^4.4 || ^5.0 || ^6.0",
"symfony/http-kernel": "^4.4 || ^5.0 || ^6.0",
"symfony/phpunit-bridge": "^5.4@dev || ^6.0"
},
"suggest": {
"nyholm/psr7": "For a super lightweight PSR-7/17 implementation"
},
"type": "symfony-bridge",
"extra": {
"branch-alias": {
"dev-main": "2.1-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Bridge\\PsrHttpMessage\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "PSR HTTP message bridge",
"homepage": "http://symfony.com",
"keywords": [
"http",
"http-message",
"psr-17",
"psr-7"
],
"support": {
"issues": "https://github.com/symfony/psr-http-message-bridge/issues",
"source": "https://github.com/symfony/psr-http-message-bridge/tree/v2.1.2"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2021-11-05T13:13:39+00:00"
},
{
"name": "symfony/routing",
"version": "v6.0.11",

View File

@ -13,31 +13,28 @@ namespace Plugin\Social\Controllers;
use Beike\Models\Customer;
use Illuminate\Support\Facades\Auth;
use Overtrue\Socialite\Exceptions\Exception;
use Overtrue\Socialite\SocialiteManager;
use Illuminate\Support\Facades\Config;
use Laravel\Socialite\Facades\Socialite;
use Beike\Admin\Http\Controllers\Controller;
use Plugin\Social\Repositories\CustomerRepo;
class ShopSocialController extends Controller
{
private SocialiteManager $socialite;
public function __construct()
{
$config = [];
$providerSettings = plugin_setting('social.setting');
foreach ($providerSettings as $providerSetting) {
$provider = $providerSetting['provider'];
if (empty($provider)) {
continue;
}
$config[$provider] = [
$config = [
'client_id' => $providerSetting['key'],
'client_secret' => $providerSetting['secret'],
'redirect' => plugin_route('social.callback', $provider),
];
Config::set("services.{$provider}", $config);
}
$this->socialite = new SocialiteManager($config);
}
/**
@ -46,34 +43,26 @@ class ShopSocialController extends Controller
*/
public function redirect($provider)
{
if (!defined(\Overtrue\Socialite\Contracts\ABNF_OPEN_ID)) {
require_once app_path() . '/../vendor/overtrue/socialite/src/Contracts/FactoryInterface.php';
require_once app_path() . '/../vendor/overtrue/socialite/src/Contracts/ProviderInterface.php';
require_once app_path() . '/../vendor/overtrue/socialite/src/Contracts/UserInterface.php';
try {
return Socialite::driver($provider)->redirect();
} catch (\Exception $e) {
die($e->getMessage());
}
$url = $this->socialite->create($provider)->redirect();
return redirect($url);
}
/**
* @param $provider
* @return mixed
* @throws Exception
*/
public function callback($provider)
{
$code = request('code');
$driver = $this->socialite->create($provider);
// For google, facebook, twitter in China.
$driver->setGuzzleOptions([
// 'proxy' => '127.0.0.1:7890'
]);
$userData = $driver->userFromCode($code);
$customer = CustomerRepo::createCustomer($provider, $userData);
Auth::guard(Customer::AUTH_GUARD)->login($customer);
return view('Social::shop/callback');
try {
$userData = Socialite::driver($provider)->user();
$customer = CustomerRepo::createCustomer($provider, $userData);
Auth::guard(Customer::AUTH_GUARD)->login($customer);
return view('Social::shop/callback');
} catch (\Exception $e) {
die($e->getMessage());
}
}
}

View File

@ -29,6 +29,7 @@ return [
'qq' => 'QQ',
'taobao' => 'Taobao',
'tapd' => 'Tapd',
'twitter' => 'Twitter',
'wechat' => 'Wechat',
'wework' => 'Wework',
'weibo' => 'Weibo',

View File

@ -14,7 +14,7 @@ return [
'text_module' => 'Modules',
'text_success' => 'Success: You have modified module OpenCart OmniAuth!',
'text_copyright' => 'OpenCart.cn <a href="http://www.opencart.cn" target="_blank">OmniAuth</a> &copy; %s',
'text_omni_explain' => 'This plugin supports WeChat scan code, WeChat Official, QQ, Weibo, Facebook, Google, Twitter and others Social Network',
'text_omni_explain' => 'This plugin supports Facebook, Twitter, Google etc.',
'text_omni_explain_2' => 'To use a third-party login, you need to apply to the corresponding platform, and fill in the obtained ID and key to the corresponding input box.',
'text_wechat_title' => 'WeChat scan code login application address',
'text_wechat_info' => 'WeChat open platform',
@ -24,7 +24,7 @@ return [
'text_weibo_info' => 'Weibo open platform',
'text_facebook_title' => 'Facebook login application address',
'text_google_title' => 'Google login application address',
'text_Twitter_title' => 'Twitter login application address',
'text_twitter_title' => 'Twitter login application address',
'text_help_msg' => 'help information',
// Entry

View File

@ -28,7 +28,8 @@ return [
'qcloud' => '腾讯云',
'qq' => 'QQ',
'taobao' => '淘宝',
'tapd' => 'tapd',
'tapd' => 'Tapd',
'twitter' => 'Twitter',
'wechat' => '微信',
'wework' => '企业微信',
'weibo' => '微博',

View File

@ -14,7 +14,7 @@ return [
'text_module' => '模块',
'text_success' => '成功: 您成功修改第三方登录配置!',
'text_copyright' => 'OpenCart.cn <a href="http://www.opencart.cn" target="_blank">获取帮助</a> &copy; %s',
'text_omni_explain' => '本模块支持微信扫码, 微信公众号, QQ, 微博FacebookGoogleTwitter等第三方登录',
'text_omni_explain' => '本模块支持微Facebook, Twitter, Google等第三方登录',
'text_omni_explain_2' => '要使用第三方登录, 需要到对应平台申请开通, 并把获取到的 ID 和密钥填写到上面对应的输入框',
'text_wechat_title' => '微信扫码登录申请地址',
'text_wechat_info' => '微信开放平台',
@ -24,7 +24,7 @@ return [
'text_weibo_info' => '微博开放平台',
'text_facebook_title' => 'Facebook登录申请地址',
'text_google_title' => 'Google登录申请地址',
'text_Twitter_title' => 'Twitter登录申请地址',
'text_twitter_title' => 'Twitter登录申请地址',
'text_help_msg' => '帮助信息',
// Entry

View File

@ -12,13 +12,11 @@
namespace Plugin\Social\Repositories;
use Beike\Models\Customer;
use Overtrue\Socialite\User;
use Overtrue\Socialite\Providers;
use Laravel\Socialite\Two\User;
use Beike\Shop\Services\AccountService;
use Illuminate\Database\Eloquent\Model;
use Plugin\Social\Models\CustomerSocial;
use Illuminate\Database\Eloquent\Builder;
use Overtrue\Socialite\Exceptions\Exception;
class CustomerRepo
{
@ -26,28 +24,9 @@ class CustomerRepo
* 允许的第三方服务
*/
private const PROVIDERS = [
Providers\Alipay::NAME,
Providers\Azure::NAME,
Providers\DingTalk::NAME,
Providers\DouYin::NAME,
Providers\Douban::NAME,
Providers\Facebook::NAME,
Providers\FeiShu::NAME,
// Providers\Figma::NAME,
// Providers\GitHub::NAME,
// Providers\Gitee::NAME,
Providers\Google::NAME,
Providers\Line::NAME,
Providers\Linkedin::NAME,
// Providers\OpenWeWork::NAME,
Providers\Outlook::NAME,
// Providers\QCloud::NAME,
Providers\QQ::NAME,
// Providers\Taobao::NAME,
// Providers\Tapd::NAME,
Providers\WeChat::NAME,
// Providers\WeWork::NAME,
Providers\Weibo::NAME,
'facebook',
'twitter',
'google',
];
public static function allProviders(): array
@ -68,7 +47,6 @@ class CustomerRepo
* @param $provider
* @param User $userData
* @return Customer
* @throws Exception
*/
public static function createCustomer($provider, User $userData): Customer
{
@ -84,7 +62,7 @@ class CustomerRepo
$customerData = [
'from' => $provider,
'email' => $userData->getEmail(),
'name' => $userData->getNickname(),
'name' => $userData->getName(),
'avatar' => $userData->getAvatar(),
];
$customer = AccountService::register($customerData);
@ -100,7 +78,6 @@ class CustomerRepo
* @param $provider
* @param User $userData
* @return Model|Builder
* @throws Exception
*/
public static function createSocial($customer, $provider, User $userData): Model|Builder
{
@ -114,8 +91,8 @@ class CustomerRepo
'provider' => $provider,
'user_id' => $userData->getId(),
'union_id' => '',
'access_token' => $userData->getAccessToken(),
'extra' => $userData->toJSON()
'access_token' => $userData->token,
'extra' => json_encode($userData->getRaw())
];
return CustomerSocial::query()->create($socialData);
}

View File

@ -72,8 +72,8 @@
<td>
<el-form-item label="" class="mb-0">
<div class="input-group">
<input size="small" class="form-control" :value="callbackUrl(item.callback)" disabled placeholder="{{ __('Social::setting.entry_callback') }}"></input>
<a href="javascript:void(0)" class="btn btn-outline-secondary opacity-75 copy-code" :data-clipboard-text="item.callback"><i class="bi bi-front"></i></a>
<input size="small" class="form-control" :value="item.callback" disabled placeholder="{{ __('Social::setting.entry_callback') }}"></input>
<a href="javascript:void(0)" class="btn btn-outline-secondary opacity-75 copy-code" :data-clipboard-text="item.callback" @click="copyCode"><i class="bi bi-front"></i></a>
</div>
</el-form-item>
</td>
@ -99,23 +99,14 @@
<ol class="list-group list-group-numbered lh-lg text-secondary">
<li>{{ __('Social::setting.text_omni_explain') }}</li>
<li>{{ __('Social::setting.text_omni_explain_2') }}</li>
<li>{{ __('Social::setting.text_wechat_title') }}
<a target="_blank" href="https://open.weixin.qq.com/">{{ __('Social::setting.text_wechat_info') }}</a>
</li>
<li>{{ __('Social::setting.text_qq_title') }}
<a target="_blank" href="https://connect.qq.com/">{{ __('Social::setting.text_qq_info') }}</a>
</li>
<li>{{ __('Social::setting.text_weibo_title') }}
<a target="_blank" href="http://open.weibo.com/">{{ __('Social::setting.text_weibo_info') }}</a>
</li>
<li>{{ __('Social::setting.text_facebook_title') }}
<a target="_blank" href="https://developers.facebook.com/">Facebook</a>
</li>
<li>{{ __('Social::setting.text_google_title') }}
<a target="_blank" href="https://console.developers.google.com/projectcreate/">Google</a>
<li>{{ __('Social::setting.text_twitter_title') }}
<a target="_blank" href="https://developer.twitter.com/">Twitter</a>
</li>
<li>{{ __('Social::setting.text_Twitter_title') }}
<a target="_blank" href="https://apps.twitter.com/">Twitter</a>
<li>{{ __('Social::setting.text_google_title') }}
<a target="_blank" href="https://console.developers.google.com/">Google</a>
</li>
.......
</ol>
@ -181,19 +172,19 @@
});
},
callbackUrl(code) {
return `{{ shop_route('home.index') }}/${code}`;
},
providerChange(e, index) {
this.form.social[index].callback = 'plugin/social/callbacks/' + e
this.form.social[index].callback = `{{ shop_route('home.index') }}/plugin/social/callbacks/${e}`
},
addRow() {
let providers = this.source.providers.filter(e => !this.form.social.some(s => s.provider == e.code))
if (providers.length) {
this.form.social.push({provider: providers[0].code, status: 1, key: '', secret: '', callback: `plugin/social/callbacks/${this.source.providers[1].code}`, sort_order: this.form.social.length})
this.form.social.push({provider: providers[0].code, status: 1, key: '', secret: '', callback: `{{ shop_route('home.index') }}/plugin/social/callbacks/${this.source.providers[0].code}`, sort_order: this.form.social.length})
}
},
copyCode() {
layer.msg('Ok');
}
}
})

View File

@ -1,7 +1,7 @@
{
"code": "social",
"name": "Social",
"description": "第三方登录(包括微信、QQ、微博、Google、Facebook)",
"description": "第三方登录(包括Facebook、Twitter、Google)",
"type": "social",
"version": "v1.0.0",
"icon": "/image/logo.png",