mirror of
				https://github.com/v2board/v2board.git
				synced 2025-10-31 17:31:49 +08:00 
			
		
		
		
	update: weak password risk
This commit is contained in:
		| @@ -7,6 +7,7 @@ use App\Http\Requests\Passport\AuthRegister; | |||||||
| use App\Http\Requests\Passport\AuthForget; | use App\Http\Requests\Passport\AuthForget; | ||||||
| use App\Http\Requests\Passport\AuthLogin; | use App\Http\Requests\Passport\AuthLogin; | ||||||
| use App\Jobs\SendEmailJob; | use App\Jobs\SendEmailJob; | ||||||
|  | use App\Services\AuthService; | ||||||
| use Illuminate\Http\Request; | use Illuminate\Http\Request; | ||||||
| use Illuminate\Support\Facades\Cache; | use Illuminate\Support\Facades\Cache; | ||||||
| use App\Models\Plan; | use App\Models\Plan; | ||||||
| @@ -16,6 +17,7 @@ use App\Utils\Helper; | |||||||
| use App\Utils\Dict; | use App\Utils\Dict; | ||||||
| use App\Utils\CacheKey; | use App\Utils\CacheKey; | ||||||
| use ReCaptcha\ReCaptcha; | use ReCaptcha\ReCaptcha; | ||||||
|  | use Firebase\JWT\JWT; | ||||||
|  |  | ||||||
| class AuthController extends Controller | class AuthController extends Controller | ||||||
| { | { | ||||||
| @@ -165,11 +167,6 @@ class AuthController extends Controller | |||||||
|             Cache::forget(CacheKey::get('EMAIL_VERIFY_CODE', $request->input('email'))); |             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->last_login_at = time(); | ||||||
|         $user->save(); |         $user->save(); | ||||||
|  |  | ||||||
| @@ -180,8 +177,11 @@ class AuthController extends Controller | |||||||
|                 (int)config('v2board.register_limit_expire', 60) * 60 |                 (int)config('v2board.register_limit_expire', 60) * 60 | ||||||
|             ); |             ); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         $authService = new AuthService($user); | ||||||
|  |  | ||||||
|         return response()->json([ |         return response()->json([ | ||||||
|             'data' => $data |             'data' => $authService->generateAuthData('register') | ||||||
|         ]); |         ]); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -207,14 +207,9 @@ class AuthController extends Controller | |||||||
|             abort(500, __('Your account has been suspended')); |             abort(500, __('Your account has been suspended')); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         $data = [ |         $authService = new AuthService($user); | ||||||
|             'token' => $user->token, |  | ||||||
|             'auth_data' => base64_encode("{$user->email}:{$user->password}") |  | ||||||
|         ]; |  | ||||||
|  |  | ||||||
|         if ($user->is_admin) $data['is_admin'] = true; |  | ||||||
|         return response([ |         return response([ | ||||||
|             'data' => $data |             'data' => $authService->generateAuthData('login') | ||||||
|         ]); |         ]); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -243,49 +238,25 @@ class AuthController extends Controller | |||||||
|             if ($user->banned) { |             if ($user->banned) { | ||||||
|                 abort(500, __('Your account has been suspended')); |                 abort(500, __('Your account has been suspended')); | ||||||
|             } |             } | ||||||
|             $data = [ |  | ||||||
|                 'token' => $user->token, |  | ||||||
|                 'auth_data' => base64_encode("{$user->email}:{$user->password}") |  | ||||||
|             ]; |  | ||||||
|             Cache::forget($key); |             Cache::forget($key); | ||||||
|  |             $authService = new AuthService($user); | ||||||
|             return response([ |             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) |     public function getQuickLoginUrl(Request $request) | ||||||
|     { |     { | ||||||
|         $authorization = $request->input('auth_data') ?? $request->header('authorization'); |         $authorization = $request->input('auth_data') ?? $request->header('authorization'); | ||||||
|         if (!$authorization) abort(403, '未登录或登陆已过期'); |         if (!$authorization) abort(403, '未登录或登陆已过期'); | ||||||
|  |  | ||||||
|         $authData = explode(':', base64_decode($authorization)); |         $user = AuthService::decryptAuthData($authorization); | ||||||
|         if (!isset($authData[0]) || !isset($authData[1])) abort(403, __('Token error')); |         if (!$user) abort(403, '未登录或登陆已过期'); | ||||||
|         $user = User::where('email', $authData[0]) |  | ||||||
|             ->where('password', $authData[1]) |  | ||||||
|             ->first(); |  | ||||||
|         if (!$user) { |  | ||||||
|             abort(500, __('Token error')); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         $code = Helper::guid(); |         $code = Helper::guid(); | ||||||
|         $key = CacheKey::get('TEMP_TOKEN', $code); |         $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'); |         $redirect = '/#/login?verify=' . $code . '&redirect=' . ($request->input('redirect') ? $request->input('redirect') : 'dashboard'); | ||||||
|         if (config('v2board.app_url')) { |         if (config('v2board.app_url')) { | ||||||
|             $url = config('v2board.app_url') . $redirect; |             $url = config('v2board.app_url') . $redirect; | ||||||
|   | |||||||
| @@ -2,6 +2,7 @@ | |||||||
|  |  | ||||||
| namespace App\Http\Middleware; | namespace App\Http\Middleware; | ||||||
|  |  | ||||||
|  | use App\Services\AuthService; | ||||||
| use Closure; | use Closure; | ||||||
| use Illuminate\Support\Facades\Cache; | use Illuminate\Support\Facades\Cache; | ||||||
|  |  | ||||||
| @@ -19,24 +20,10 @@ class Admin | |||||||
|         $authorization = $request->input('auth_data') ?? $request->header('authorization'); |         $authorization = $request->input('auth_data') ?? $request->header('authorization'); | ||||||
|         if (!$authorization) abort(403, '未登录或登陆已过期'); |         if (!$authorization) abort(403, '未登录或登陆已过期'); | ||||||
|  |  | ||||||
|         $authData = explode(':', base64_decode($authorization)); |         $user = AuthService::decryptAuthData($authorization); | ||||||
|         if (!Cache::has($authorization)) { |         if (!$user || !$user['is_admin']) abort(403, '未登录或登陆已过期'); | ||||||
|             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); |  | ||||||
|         } |  | ||||||
|         $request->merge([ |         $request->merge([ | ||||||
|             'user' => Cache::get($authorization) |             'user' => $user | ||||||
|         ]); |         ]); | ||||||
|         return $next($request); |         return $next($request); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -2,8 +2,8 @@ | |||||||
|  |  | ||||||
| namespace App\Http\Middleware; | namespace App\Http\Middleware; | ||||||
|  |  | ||||||
|  | use App\Services\AuthService; | ||||||
| use Closure; | use Closure; | ||||||
| use Illuminate\Support\Facades\Cache; |  | ||||||
|  |  | ||||||
| class Staff | class Staff | ||||||
| { | { | ||||||
| @@ -19,24 +19,10 @@ class Staff | |||||||
|         $authorization = $request->input('auth_data') ?? $request->header('authorization'); |         $authorization = $request->input('auth_data') ?? $request->header('authorization'); | ||||||
|         if (!$authorization) abort(403, '未登录或登陆已过期'); |         if (!$authorization) abort(403, '未登录或登陆已过期'); | ||||||
|  |  | ||||||
|         $authData = explode(':', base64_decode($authorization)); |         $user = AuthService::decryptAuthData($authorization); | ||||||
|         if (!Cache::has($authorization)) { |         if (!$user || !$user['is_staff']) abort(403, '未登录或登陆已过期'); | ||||||
|             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); |  | ||||||
|         } |  | ||||||
|         $request->merge([ |         $request->merge([ | ||||||
|             'user' => Cache::get($authorization) |             'user' => $user | ||||||
|         ]); |         ]); | ||||||
|         return $next($request); |         return $next($request); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -2,6 +2,7 @@ | |||||||
|  |  | ||||||
| namespace App\Http\Middleware; | namespace App\Http\Middleware; | ||||||
|  |  | ||||||
|  | use App\Services\AuthService; | ||||||
| use Closure; | use Closure; | ||||||
| use Illuminate\Support\Facades\Cache; | use Illuminate\Support\Facades\Cache; | ||||||
|  |  | ||||||
| @@ -19,23 +20,10 @@ class User | |||||||
|         $authorization = $request->input('auth_data') ?? $request->header('authorization'); |         $authorization = $request->input('auth_data') ?? $request->header('authorization'); | ||||||
|         if (!$authorization) abort(403, '未登录或登陆已过期'); |         if (!$authorization) abort(403, '未登录或登陆已过期'); | ||||||
|  |  | ||||||
|         $authData = explode(':', base64_decode($authorization)); |         $user = AuthService::decryptAuthData($authorization); | ||||||
|         if (!Cache::has($authorization)) { |         if (!$user) abort(403, '未登录或登陆已过期'); | ||||||
|             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); |  | ||||||
|         } |  | ||||||
|         $request->merge([ |         $request->merge([ | ||||||
|             'user' => Cache::get($authorization) |             'user' => $user | ||||||
|         ]); |         ]); | ||||||
|         return $next($request); |         return $next($request); | ||||||
|     } |     } | ||||||
|   | |||||||
							
								
								
									
										54
									
								
								app/Services/AuthService.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								app/Services/AuthService.php
									
									
									
									
									
										Normal file
									
								
							| @@ -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; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -13,6 +13,7 @@ | |||||||
|     "require": { |     "require": { | ||||||
|         "php": "^7.3.0|^8.0", |         "php": "^7.3.0|^8.0", | ||||||
|         "fideloper/proxy": "^4.4", |         "fideloper/proxy": "^4.4", | ||||||
|  |         "firebase/php-jwt": "^6.3", | ||||||
|         "fruitcake/laravel-cors": "^2.0", |         "fruitcake/laravel-cors": "^2.0", | ||||||
|         "google/recaptcha": "^1.2", |         "google/recaptcha": "^1.2", | ||||||
|         "guzzlehttp/guzzle": "^7.4.3", |         "guzzlehttp/guzzle": "^7.4.3", | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user