mirror of
https://github.com/ProxyPanel/ProxyPanel.git
synced 2026-04-11 23:19:05 +00:00
Fixed OAuth not function and improve the code quality
This commit is contained in:
@@ -13,118 +13,140 @@ use Str;
|
||||
|
||||
class OAuthController extends Controller
|
||||
{
|
||||
public function simple(string $type): RedirectResponse
|
||||
{
|
||||
$info = Socialite::driver($type)->stateless()->user();
|
||||
if ($info) {
|
||||
$user = Auth::user();
|
||||
|
||||
if ($user) {
|
||||
return $this->binding($type, $user, $info);
|
||||
}
|
||||
|
||||
return $this->logging($type, $info);
|
||||
}
|
||||
|
||||
return redirect()->route('login')->withErrors(trans('auth.oauth.login_failed'));
|
||||
}
|
||||
|
||||
private function binding(string $type, User $user, \Laravel\Socialite\Contracts\User $OauthUser): RedirectResponse
|
||||
{
|
||||
$data = ['type' => $type, 'identifier' => $OauthUser->getId(), 'credential' => $OauthUser->token];
|
||||
if ($user->userAuths()->whereType($type)->updateOrCreate($data)) {
|
||||
return redirect()->route('profile')->with('successMsg', trans('auth.oauth.bind_success'));
|
||||
}
|
||||
|
||||
return redirect()->route('profile')->withErrors(trans('auth.oauth.bind_failed'));
|
||||
}
|
||||
|
||||
private function logging(string $type, \Laravel\Socialite\Contracts\User $OauthUser): RedirectResponse
|
||||
{
|
||||
$user = User::whereUsername($OauthUser->getEmail())->first();
|
||||
if (! isset($user)) {
|
||||
$auth = UserOauth::whereType($type)->whereIdentifier($OauthUser->getId())->first();
|
||||
if (isset($auth)) {
|
||||
$user = $auth->user;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($user)) {
|
||||
Auth::login($user);
|
||||
Helpers::userLoginAction($user, IP::getClientIp()); // 用户登录后操作
|
||||
|
||||
return redirect()->route('login');
|
||||
}
|
||||
|
||||
return redirect()->route('login')->withErrors(trans('auth.error.not_found_user'));
|
||||
}
|
||||
|
||||
public function login(string $type): RedirectResponse
|
||||
{
|
||||
$info = Socialite::driver($type)->stateless()->user();
|
||||
if ($info) {
|
||||
return $this->logging($type, $info);
|
||||
}
|
||||
|
||||
return redirect()->route('login')->withErrors(trans('auth.oauth.login_failed'));
|
||||
}
|
||||
|
||||
public function unbind(string $type): RedirectResponse
|
||||
public function unbind(string $provider): RedirectResponse
|
||||
{
|
||||
$user = Auth::user();
|
||||
if ($user && $user->userAuths()->whereType($type)->delete()) {
|
||||
|
||||
if ($user && $user->userAuths()->whereType($provider)->delete()) {
|
||||
return redirect()->route('profile')->with('successMsg', trans('auth.oauth.unbind_success'));
|
||||
}
|
||||
|
||||
return redirect()->route('profile')->with('successMsg', trans('auth.oauth.unbind_failed'));
|
||||
return redirect()->route('profile')->withErrors(trans('auth.oauth.unbind_failed'));
|
||||
}
|
||||
|
||||
public function bind(string $type): RedirectResponse
|
||||
public function bind(string $provider): RedirectResponse
|
||||
{
|
||||
$info = Socialite::driver($type)->stateless()->user();
|
||||
config(["services.$provider.redirect" => route('oauth.bind', ['provider' => $provider])]);
|
||||
$authInfo = Socialite::driver($provider)->stateless()->user();
|
||||
|
||||
if ($info) {
|
||||
$user = Auth::user();
|
||||
if ($user) {
|
||||
return $this->binding($type, $user, $info);
|
||||
}
|
||||
if (! $authInfo) {
|
||||
return redirect()->route('login')->withErrors(trans('auth.oauth.login_failed'));
|
||||
}
|
||||
|
||||
$user = Auth::user();
|
||||
|
||||
if (! $user) {
|
||||
return redirect()->route('profile')->withErrors(trans('auth.oauth.bind_failed'));
|
||||
}
|
||||
|
||||
return redirect()->route('login')->withErrors(trans('auth.oauth.login_failed'));
|
||||
return $this->bindLogic($provider, $user, $authInfo);
|
||||
}
|
||||
|
||||
public function register(string $type): RedirectResponse
|
||||
private function bindLogic(string $provider, User $user, \Laravel\Socialite\Contracts\User $authInfo): RedirectResponse
|
||||
{
|
||||
$data = [
|
||||
'type' => $provider,
|
||||
'identifier' => $authInfo->getId(),
|
||||
'credential' => $authInfo->token,
|
||||
];
|
||||
|
||||
$auth = $user->userAuths()->whereType($provider)->first();
|
||||
|
||||
if ($auth) {
|
||||
$user->userAuths()->whereType($provider)->update($data);
|
||||
$message = trans('auth.oauth.rebind_success');
|
||||
} else {
|
||||
$user->userAuths()->create($data);
|
||||
$message = trans('auth.oauth.bind_success');
|
||||
}
|
||||
|
||||
return redirect()->route('profile')->with('successMsg', $message);
|
||||
}
|
||||
|
||||
public function register(string $provider): RedirectResponse
|
||||
{
|
||||
config(["services.$provider.redirect" => route('oauth.register', ['provider' => $provider])]);
|
||||
if (! sysConfig('is_register')) {
|
||||
return redirect()->route('register')->withErrors(trans('auth.register.error.disable'));
|
||||
}
|
||||
|
||||
if ((int) sysConfig('is_invite_register') === 2) { // 必须使用邀请码
|
||||
if ((int) sysConfig('is_invite_register') === 2) {
|
||||
return redirect()->route('register')->withErrors(trans('validation.required', ['attribute' => trans('auth.invite.attribute')]));
|
||||
}
|
||||
|
||||
$OauthUser = Socialite::driver($type)->stateless()->user();
|
||||
$registerInfo = Socialite::driver($provider)->stateless()->user();
|
||||
|
||||
if ($OauthUser) {
|
||||
if (User::whereUsername($OauthUser->getEmail())->doesntExist() && UserOauth::whereIdentifier($OauthUser->getId())->doesntExist()) { // 排除重复用户注册
|
||||
$user = Helpers::addUser($OauthUser->getEmail(), Str::random(), MiB * sysConfig('default_traffic'), (int) sysConfig('default_days'), $OauthUser->getNickname());
|
||||
if (! $registerInfo) {
|
||||
return redirect()->route('login')->withErrors(trans('auth.oauth.login_failed'));
|
||||
}
|
||||
|
||||
$user = User::whereUsername($registerInfo->getEmail())->first();
|
||||
|
||||
if (! $user) { // 邮箱未被注册
|
||||
$userAuth = UserOauth::whereType($provider)->whereIdentifier($registerInfo->getId())->first();
|
||||
|
||||
if (! $userAuth) { // 第三方账号未被绑定
|
||||
$user = Helpers::addUser($registerInfo->getEmail(), Str::random(), MiB * sysConfig('default_traffic'), (int) sysConfig('default_days'), $registerInfo->getNickname());
|
||||
|
||||
$user->userAuths()->create([
|
||||
'type' => $type,
|
||||
'identifier' => $OauthUser->getId(),
|
||||
'credential' => $OauthUser->token,
|
||||
'type' => $provider,
|
||||
'identifier' => $registerInfo->getId(),
|
||||
'credential' => $registerInfo->token,
|
||||
]);
|
||||
|
||||
Auth::login($user);
|
||||
return $this->handleLogin($user);
|
||||
}
|
||||
}
|
||||
|
||||
return redirect()->route('login');
|
||||
return redirect()->route('login')->withErrors(trans('auth.oauth.registered'));
|
||||
}
|
||||
|
||||
private function handleLogin(User $user): RedirectResponse
|
||||
{
|
||||
Auth::login($user);
|
||||
Helpers::userLoginAction($user, IP::getClientIp());
|
||||
|
||||
return redirect()->route('login');
|
||||
}
|
||||
|
||||
public function login(string $provider): RedirectResponse
|
||||
{
|
||||
config(["services.$provider.redirect" => route('oauth.login', ['provider' => $provider])]);
|
||||
$authInfo = Socialite::driver($provider)->stateless()->user();
|
||||
|
||||
if ($authInfo) {
|
||||
$auth = UserOauth::whereType($provider)->whereIdentifier($authInfo->getId())->first();
|
||||
|
||||
if ($auth && ($user = $auth->user)) { // 如果第三方登录有记录,直接登录用户
|
||||
return $this->handleLogin($user);
|
||||
}
|
||||
|
||||
return redirect()->route('login')->withErrors(trans('auth.oauth.registered'));
|
||||
$user = User::whereUsername($authInfo->getEmail())->first();
|
||||
|
||||
if ($user) { // 如果用户存在,执行绑定逻辑并登录用户
|
||||
$this->bindLogic($provider, $user, $authInfo);
|
||||
|
||||
return $this->handleLogin($user);
|
||||
}
|
||||
|
||||
// 如果用户不存在,则返回错误消息
|
||||
return redirect()->route('login')->withErrors(trans('auth.error.not_found_user'));
|
||||
}
|
||||
|
||||
return redirect()->route('login')->withErrors(trans('auth.oauth.login_failed'));
|
||||
}
|
||||
|
||||
public function redirect(string $provider, string $operation = 'login'): RedirectResponse
|
||||
{
|
||||
$redirectRoutes = [
|
||||
'bind' => 'oauth.bind',
|
||||
'register' => 'oauth.register',
|
||||
'login' => 'oauth.login',
|
||||
];
|
||||
|
||||
$key = "services.$provider.redirect";
|
||||
config([$key => route($redirectRoutes[$operation], ['provider' => $provider])]);
|
||||
|
||||
return Socialite::driver($provider)->stateless()->redirect();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,14 +36,14 @@
|
||||
<div class="line">
|
||||
<span> {{ trans('auth.one-click_login') }} </span>
|
||||
</div>
|
||||
@foreach (json_decode(sysConfig('oauth_path')) as $item)
|
||||
@if ($item === 'telegram')
|
||||
@foreach (json_decode(sysConfig('oauth_path')) as $provider)
|
||||
@if ($provider === 'telegram')
|
||||
<div>
|
||||
{!! Socialite::driver('telegram')->getButton() !!}
|
||||
</div>
|
||||
@else
|
||||
<a class="btn btn-icon btn-pure" href="{{route('oauth.login', ['type' => $item])}}">
|
||||
<i class="fa-brands {{config('common.oauth.icon')[$item]}} fa-lg" aria-hidden="true"></i>
|
||||
<a class="btn btn-icon btn-pure" href="{{route('oauth.route', ['provider' => $provider, 'operation' => 'login'])}}">
|
||||
<i class="fa-brands {{config('common.oauth.icon')[$provider]}} fa-lg" aria-hidden="true"></i>
|
||||
</a>
|
||||
@endif
|
||||
@endforeach
|
||||
|
||||
@@ -106,10 +106,10 @@
|
||||
<div class="line">
|
||||
<span> {{trans('auth.oauth.register')}} </span>
|
||||
</div>
|
||||
@foreach (json_decode(sysConfig('oauth_path')) as $item)
|
||||
@if ($item !== 'telegram')
|
||||
<a class="btn btn-icon btn-pure" href="{{route('oauth.register', ['type' => $item])}}">
|
||||
<i class="fa-brands {{config('common.oauth.icon')[$item]}} fa-lg" aria-hidden="true"></i>
|
||||
@foreach (json_decode(sysConfig('oauth_path')) as $provider)
|
||||
@if ($provider !== 'telegram')
|
||||
<a class="btn btn-icon btn-pure" href="{{route('oauth.route', ['provider' => $provider, 'operation' => 'register'])}}">
|
||||
<i class="fa-brands {{config('common.oauth.icon')[$provider]}} fa-lg" aria-hidden="true"></i>
|
||||
</a>
|
||||
@endif
|
||||
@endforeach
|
||||
|
||||
@@ -42,22 +42,22 @@
|
||||
<span> {{trans('user.oauth.bind_title')}} </span>
|
||||
</div>
|
||||
<div class="user-socials list-group-gap list-group-full row m-0">
|
||||
@foreach (json_decode(sysConfig('oauth_path')) as $item)
|
||||
<a class="list-group-item justify-content-center @if(in_array($item, $auth, true)) col-10 @else col-12 @endif"
|
||||
@if($item !== 'telegram') href="{{route('oauth.bind', ['type' => $item])}}" @endif>
|
||||
<i class="fa-brands {{ config('common.oauth.icon')[$item] }} fa-lg mr-10" aria-hidden="true"></i> {{ ucfirst($item) }}
|
||||
@foreach (json_decode(sysConfig('oauth_path')) as $provider)
|
||||
<a class="list-group-item justify-content-center @if(in_array($provider, $auth, true)) col-10 @else col-12 @endif"
|
||||
@if($provider !== 'telegram') href="{{route('oauth.route', ['provider' => $provider, 'operation' => 'bind'])}}" @endif>
|
||||
<i class="fa-brands {{ config('common.oauth.icon')[$provider] }} fa-lg mr-10" aria-hidden="true"></i> {{ ucfirst($provider) }}
|
||||
:
|
||||
@if(in_array($item, $auth, true))
|
||||
@if(in_array($provider, $auth, true))
|
||||
<span class="red-600">{{trans('user.oauth.rebind')}}</span>
|
||||
@else
|
||||
<span class="grey-500">{{trans('user.oauth.not_bind')}}</span>
|
||||
@endif
|
||||
@if($item === 'telegram')
|
||||
@if($provider === 'telegram')
|
||||
{!! Socialite::driver('telegram')->getButton() !!}
|
||||
@endif
|
||||
</a>
|
||||
@if(in_array($item, $auth, true))
|
||||
<a class="col-2 btn btn-block btn-danger my-auto" href="{{route('oauth.unbind', ['type' => $item])}}">{{trans('user.oauth.unbind')}}</a>
|
||||
@if(in_array($provider, $auth, true))
|
||||
<a class="col-2 btn btn-block btn-danger my-auto" href="{{route('oauth.unbind', ['provider' => $provider])}}">{{trans('user.oauth.unbind')}}</a>
|
||||
@endif
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
@@ -22,11 +22,11 @@ Route::get('/message/{type}/{msg_id}/show', [MessageController::class, 'index'])
|
||||
|
||||
Route::middleware(['isForbidden', 'affiliate', 'isMaintenance'])->group(function () { // 登录相关
|
||||
Route::prefix('oauth')->name('oauth.')->controller(OAuthController::class)->group(function () { // 用户第三方登录默认登录/转跳方式
|
||||
Route::get('{type}/login', 'login')->name('login');
|
||||
Route::get('{type}/register', 'register')->name('register');
|
||||
Route::get('{type}/bind', 'bind')->name('bind');
|
||||
Route::get('{type}/unbind', 'unbind')->name('unbind');
|
||||
Route::get('{type}/redirect', 'simple')->name('simple');
|
||||
Route::get('{provider}/redirect/{operation}', 'redirect')->whereIn('operation', ['bind', 'register', 'login'])->name('route'); // 转跳
|
||||
Route::get('{provider}/unbind', 'unbind')->name('unbind'); // 解绑
|
||||
Route::get('{provider}/login', 'login')->name('login'); // 登录 callback
|
||||
Route::get('{provider}/register', 'register')->name('register'); // 注册 callback
|
||||
Route::get('{provider}/bind', 'bind')->name('bind'); // 绑定 callback
|
||||
});
|
||||
|
||||
Route::controller(AuthController::class)->group(function () {
|
||||
|
||||
Reference in New Issue
Block a user