Laravel自定义登录添加用户状态校验:禁用状态用户无法登录
自定义登录控制器添加用户状态校验方案
我帮你梳理了现有登录控制器的逻辑,最合适的添加状态校验的位置是在用户认证成功之后——也就是Auth::attempt($credentials)通过的瞬间,这时候我们已经能拿到用户实例,立刻检查status字段就能及时拦截禁用账号的登录请求。
具体修改思路:
- 在用户认证成功后,立即获取当前用户实例
- 检查用户的
status值,若为0则执行注销并返回禁用提示 - 保留原有其他业务逻辑,确保正常账号的登录流程不受影响
以下是修改后的完整登录控制器代码:
public function fdLogin(Request $request) { $credentials = $request->only('email', 'password'); $rules = [ 'email' => 'required|email', 'password' => 'required', ]; $validator = Validator::make($credentials, $rules); if ($validator->fails()) { return response()->json([ 'status' => false, 'message' => __('messages.validation_errors'), 'errors' => $validator->messages() ]); } $token = ""; try { // if Request has latitude and longitude $latFrom = $longFrom = $givenSpeciality = ""; $locationTag = false; if ($request->has('lat') && $request->has('long') && $request->has('specialityKey') && !empty($request->lat) && !empty($request->long) && !empty($request->specialityKey)) { $latFrom = $request->lat; $longFrom = $request->long; $givenSpeciality = $request->specialityKey; $locationTag = true; } if (!Auth::attempt($credentials)) { return response()->json(array('status' => false, 'message' => 'Invalid username or password', 'errors' => array('Invalid username or password'))); } // 新增:用户状态校验逻辑 $currentUser = Auth::user(); if ($currentUser->status == 0) { Auth::logout(); // 清除认证会话,避免残留状态 return response()->json([ 'status' => false, 'message' => 'Your account is disabled, please contact the administrator.', 'errors' => ['Account disabled'] ], 403); // 使用403状态码表示访问被禁止 } $speciality = DB::table('specialities') ->join('user_facility', 'specialities.id', 'user_facility.speciality_id') ->where('user_facility.user_id', Auth::user()->id) ->select('specialities.name', 'specialities.id')->first(); $types = []; if (!empty($speciality)) { $types = $speciality; } $customClaims = ['exp' => Carbon::now()->addYear()->timestamp, 'specialityType' => $types]; if (!$token = JWTAuth::claims($customClaims)->attempt($credentials)) { return response()->json([ 'status' => false, 'message' => 'We can`t find an account with this credentials.' ], 401); } } catch (JWTException $e) { // Something went wrong with JWT Auth. return response()->json([ 'status' => false, 'message' => 'Failed to login, please try again.' ], 500); } $withInFacility['logged_in_facility'] = array(); $currentUser = Auth::user(); $user_id = $currentUser->id; if ($locationTag) { $userWithFacilities = $currentUser->load('facilities.facilityLocation', 'facilities.speciality.avaliableSpeciality'); $locations = array(); if (isset($userWithFacilities['facilities']) && count($userWithFacilities['facilities'])) { foreach ($userWithFacilities['facilities'] as $facility) { $faci = $facility->toArray(); if (!empty($faci['facility_location']) && $faci['facility_location'] > 0) { $demo = $faci['facility_location']; } if (isset($faci['speciality']) && count($faci['speciality']) > 0) { $speciality = $faci['speciality']; if (isset($speciality['avaliable_speciality']) && count($speciality['avaliable_speciality']) > 0) { $avaliable_speciality = $speciality['avaliable_speciality']; $demo['avaliable'] = $avaliable_speciality['specialty_key']; } } $locations[] = $demo; } if (count($locations)) { foreach ($locations as $location) { $distance = self::distance($latFrom, $longFrom, $location['lat'], $location['long']); // if distance is less than 100 meter ''ll eligible to login else Log him out if ($distance < config('constants.facility_radius')) { if ($location['avaliable'] == $givenSpeciality) { $withInFacility['logged_in_facility'] = $location; $withInFacility['logged_in_facility']['radius'] = config('constants.facility_radius'); } } } // if distance is less than 100 meter ''ll eligible to login else Log him out if (empty($withInFacility['logged_in_facility'])) { JWTAuth::setToken($token)->invalidate(); return response()->json(['status' => false, 'message' => 'Your are not in facility OR Your speciality did not matched with facility', 'errors' => '']); } } else { return response(['status' => false, 'message' => 'Your Facility did not have any location , please ask for administrator', 'data' => null]); } } else { return response(['status' => false, 'message' => 'You did not have any facility , please ask for administrator', 'data' => null]); } } $currentUser->basicInfo = $this->userBasicInfo->where('user_id', $user_id)->first(); $is_super_admin = DB::table('users')->select('users.is_super_admin')->where('id', $user_id)->first(); $specialitiesAndRoles = DB::table('user_facility') ->leftjoin('roles', 'user_facility.role_id', 'roles.id') ->leftjoin('specialities', 'user_facility.speciality_id', '=', 'specialities.id') ->leftjoin('available_specialties', 'specialities.available_specialties_id', '=', 'available_specialties.id') ->where('user_facility.user_id', $user_id) ->select('user_facility.facility_id', 'user_facility.speciality_id', 'user_facility.is_facility_supervisor', 'user_facility.priv_key', 'user_facility.role_id', 'specialities.name', 'available_specialties.id', 'available_specialties.specialty_key') ->get(); $superadmin = $is_super_admin->is_super_admin; $specialities = (object)$specialitiesAndRoles; $sp = $specialitiesAndRoles->toArray(); $specialty_key = ""; if (!empty($sp)) { $specialty_key = $sp[0]->specialty_key; } $fac_privs = array(); if (!empty($sp)) { foreach ($sp as $s) { $s = (array)$s; $s['priv_list'] = Helpers::get_checked_privs($s); $fac_privs[] = $s; } } if (count($withInFacility['logged_in_facility'])) { $withInFacilityObj = (object)$withInFacility['logged_in_facility']; } else { $withInFacilityObj = NULL; } $response = ['is_super_admin' => $superadmin, 'facilities' => $fac_privs, 'logged_in_facility' => $withInFacilityObj]; if ($superadmin == 1) { $response['priv_ist'] = Helpers::get_priv_list(); } $speciality = $this->speciality; if ($speciality) { $user = DB::table('verify_users')->where('user_id', $user_id)->first(); DB::table('verify_users')->insert([ 'token' => $token, 'user_id' => $user_id, ]); if ($specialty_key == 'medical_doctor') { $md_db = DB::connection('doctorDB'); $user = $md_db->table('auth_token')->where('user_id', $user_id)->first(); if ($user) { $md_db->table('auth_token')->where('id', $user->id)->update([ 'token' => $token, 'isValid' => 1, ]); } else { $md_db->table('auth_token')->insert([ 'token' => $token, 'isValid' => 1, 'user_id' => $user_id ]); } } } $user_data = $this->GetUserInfo(); unset($currentUser['facilities']); return response()->json([ 'status' => true, 'message' => 'Login successfully', 'data' => [ 'token' => $token, 'userData' => $currentUser, 'userInfo' => $user_data, 'privileges' => $response, ] ]); }
关键修改说明
- 校验逻辑放在
Auth::attempt成功后,能确保禁用账号无法进入后续的JWT生成、设施校验等流程 - 发现禁用账号时,执行
Auth::logout()清除会话状态,避免残留认证信息 - 使用403状态码返回提示,符合HTTP语义,前端也能更准确地处理错误
内容的提问来源于stack exchange,提问作者syed1234
相关产品推荐
相关产品推荐

