diff --git a/app/Http/Controllers/Passport/AuthController.php b/app/Http/Controllers/Passport/AuthController.php index 7df442b7..277f1f92 100644 --- a/app/Http/Controllers/Passport/AuthController.php +++ b/app/Http/Controllers/Passport/AuthController.php @@ -7,6 +7,7 @@ use App\Http\Requests\Passport\AuthRegister; use App\Http\Requests\Passport\AuthForget; use App\Http\Requests\Passport\AuthLogin; use App\Jobs\SendEmailJob; +use App\Services\AuthService; use Illuminate\Http\Request; use Illuminate\Support\Facades\Cache; use App\Models\Plan; @@ -16,6 +17,7 @@ use App\Utils\Helper; use App\Utils\Dict; use App\Utils\CacheKey; use ReCaptcha\ReCaptcha; +use Firebase\JWT\JWT; class AuthController extends Controller { @@ -165,11 +167,6 @@ class AuthController extends Controller Cache::forget(CacheKey::get('EMAIL_VERIFY_CODE', $request->input('email'))); } - $data = [ - 'token' => $user->token, - 'auth_data' => base64_encode("{$user->email}:{$user->password}") - ]; - $user->last_login_at = time(); $user->save(); @@ -180,8 +177,11 @@ class AuthController extends Controller (int)config('v2board.register_limit_expire', 60) * 60 ); } + + $authService = new AuthService($user); + return response()->json([ - 'data' => $data + 'data' => $authService->generateAuthData('register') ]); } @@ -207,14 +207,9 @@ class AuthController extends Controller abort(500, __('Your account has been suspended')); } - $data = [ - 'token' => $user->token, - 'auth_data' => base64_encode("{$user->email}:{$user->password}") - ]; - - if ($user->is_admin) $data['is_admin'] = true; + $authService = new AuthService($user); return response([ - 'data' => $data + 'data' => $authService->generateAuthData('login') ]); } @@ -243,49 +238,25 @@ class AuthController extends Controller if ($user->banned) { abort(500, __('Your account has been suspended')); } - $data = [ - 'token' => $user->token, - 'auth_data' => base64_encode("{$user->email}:{$user->password}") - ]; Cache::forget($key); + $authService = new AuthService($user); return response([ - 'data' => $data + 'data' => $authService->generateAuthData('token') ]); } } - public function getTempToken(Request $request) - { - $user = User::where('token', $request->input('token'))->first(); - if (!$user) { - abort(500, __('Token error')); - } - - $code = Helper::guid(); - $key = CacheKey::get('TEMP_TOKEN', $code); - Cache::put($key, $user->id, 60); - return response([ - 'data' => $code - ]); - } - public function getQuickLoginUrl(Request $request) { $authorization = $request->input('auth_data') ?? $request->header('authorization'); if (!$authorization) abort(403, '未登录或登陆已过期'); - $authData = explode(':', base64_decode($authorization)); - if (!isset($authData[0]) || !isset($authData[1])) abort(403, __('Token error')); - $user = User::where('email', $authData[0]) - ->where('password', $authData[1]) - ->first(); - if (!$user) { - abort(500, __('Token error')); - } + $user = AuthService::decryptAuthData($authorization); + if (!$user) abort(403, '未登录或登陆已过期'); $code = Helper::guid(); $key = CacheKey::get('TEMP_TOKEN', $code); - Cache::put($key, $user->id, 60); + Cache::put($key, $user['id'], 60); $redirect = '/#/login?verify=' . $code . '&redirect=' . ($request->input('redirect') ? $request->input('redirect') : 'dashboard'); if (config('v2board.app_url')) { $url = config('v2board.app_url') . $redirect; diff --git a/app/Http/Middleware/Admin.php b/app/Http/Middleware/Admin.php index 90409b28..c84a88c6 100755 --- a/app/Http/Middleware/Admin.php +++ b/app/Http/Middleware/Admin.php @@ -2,6 +2,7 @@ namespace App\Http\Middleware; +use App\Services\AuthService; use Closure; use Illuminate\Support\Facades\Cache; @@ -19,24 +20,10 @@ class Admin $authorization = $request->input('auth_data') ?? $request->header('authorization'); if (!$authorization) abort(403, '未登录或登陆已过期'); - $authData = explode(':', base64_decode($authorization)); - if (!Cache::has($authorization)) { - if (!isset($authData[1]) || !isset($authData[0])) abort(403, '鉴权失败,请重新登入'); - $user = \App\Models\User::where('password', $authData[1]) - ->where('email', $authData[0]) - ->select([ - 'id', - 'email', - 'is_admin', - 'is_staff' - ]) - ->first(); - if (!$user) abort(403, '鉴权失败,请重新登入'); - if (!$user->is_admin) abort(403, '鉴权失败,请重新登入'); - Cache::put($authorization, $user->toArray(), 3600); - } + $user = AuthService::decryptAuthData($authorization); + if (!$user || !$user['is_admin']) abort(403, '未登录或登陆已过期'); $request->merge([ - 'user' => Cache::get($authorization) + 'user' => $user ]); return $next($request); } diff --git a/app/Http/Middleware/Staff.php b/app/Http/Middleware/Staff.php index 5a409833..237d278b 100644 --- a/app/Http/Middleware/Staff.php +++ b/app/Http/Middleware/Staff.php @@ -2,8 +2,8 @@ namespace App\Http\Middleware; +use App\Services\AuthService; use Closure; -use Illuminate\Support\Facades\Cache; class Staff { @@ -19,24 +19,10 @@ class Staff $authorization = $request->input('auth_data') ?? $request->header('authorization'); if (!$authorization) abort(403, '未登录或登陆已过期'); - $authData = explode(':', base64_decode($authorization)); - if (!Cache::has($authorization)) { - if (!isset($authData[1]) || !isset($authData[0])) abort(403, '鉴权失败,请重新登入'); - $user = \App\Models\User::where('password', $authData[1]) - ->where('email', $authData[0]) - ->select([ - 'id', - 'email', - 'is_admin', - 'is_staff' - ]) - ->first(); - if (!$user) abort(403, '鉴权失败,请重新登入'); - if (!$user->is_staff) abort(403, '鉴权失败,请重新登入'); - Cache::put($authorization, $user->toArray(), 3600); - } + $user = AuthService::decryptAuthData($authorization); + if (!$user || !$user['is_staff']) abort(403, '未登录或登陆已过期'); $request->merge([ - 'user' => Cache::get($authorization) + 'user' => $user ]); return $next($request); } diff --git a/app/Http/Middleware/User.php b/app/Http/Middleware/User.php index 80c0bf04..0e9ce3f7 100755 --- a/app/Http/Middleware/User.php +++ b/app/Http/Middleware/User.php @@ -2,6 +2,7 @@ namespace App\Http\Middleware; +use App\Services\AuthService; use Closure; use Illuminate\Support\Facades\Cache; @@ -19,23 +20,10 @@ class User $authorization = $request->input('auth_data') ?? $request->header('authorization'); if (!$authorization) abort(403, '未登录或登陆已过期'); - $authData = explode(':', base64_decode($authorization)); - if (!Cache::has($authorization)) { - if (!isset($authData[1]) || !isset($authData[0])) abort(403, '鉴权失败,请重新登入'); - $user = \App\Models\User::where('password', $authData[1]) - ->where('email', $authData[0]) - ->select([ - 'id', - 'email', - 'is_admin', - 'is_staff' - ]) - ->first(); - if (!$user) abort(403, '鉴权失败,请重新登入'); - Cache::put($authorization, $user->toArray(), 3600); - } + $user = AuthService::decryptAuthData($authorization); + if (!$user) abort(403, '未登录或登陆已过期'); $request->merge([ - 'user' => Cache::get($authorization) + 'user' => $user ]); return $next($request); } diff --git a/app/Services/AuthService.php b/app/Services/AuthService.php new file mode 100644 index 00000000..0d972f07 --- /dev/null +++ b/app/Services/AuthService.php @@ -0,0 +1,54 @@ +user = $user; + } + + public function generateAuthData($utm) + { + return [ + 'token' => $this->user->token, + 'is_admin' => $this->user->is_admin, + 'auth_data' => JWT::encode([ + 'expired_at' => time() + 3600, + 'id' => $this->user->id, + 'utm' => $utm, + ], config('app.key'), 'HS256') + ]; + } + + + public static function decryptAuthData($jwt) + { + try { + if (!Cache::has($jwt)) { + $data = (array)JWT::decode($jwt, new Key(config('app.key'), 'HS256')); + if ($data['expired_at'] < time()) return false; + $user = User::select([ + 'id', + 'email', + 'is_admin', + 'is_staff' + ]) + ->find($data['id']); + if (!$user) return false; + Cache::put($jwt, $user->toArray(), 3600); + } + return Cache::get($jwt); + } catch (\Exception $e) { + return false; + } + } +} diff --git a/composer.json b/composer.json index 4833b768..3463cc2d 100755 --- a/composer.json +++ b/composer.json @@ -13,6 +13,7 @@ "require": { "php": "^7.3.0|^8.0", "fideloper/proxy": "^4.4", + "firebase/php-jwt": "^6.3", "fruitcake/laravel-cors": "^2.0", "google/recaptcha": "^1.2", "guzzlehttp/guzzle": "^7.4.3",