瀏覽代碼

update: weak password risk

tokumeikoi 2 年之前
父節點
當前提交
5976bcc65a

+ 13 - 42
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;

+ 4 - 17
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);
     }

+ 4 - 18
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);
     }

+ 4 - 16
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);
     }

+ 54 - 0
app/Services/AuthService.php

@@ -0,0 +1,54 @@
+<?php
+
+namespace App\Services;
+
+use Firebase\JWT\JWT;
+use Firebase\JWT\Key;
+use App\Models\User;
+use Illuminate\Support\Facades\Cache;
+
+class AuthService
+{
+    private $user;
+
+    public function __construct($user)
+    {
+        $this->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;
+        }
+    }
+}

+ 1 - 0
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",