You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel自定义登录添加用户状态校验:禁用状态用户无法登录

自定义登录控制器添加用户状态校验方案

我帮你梳理了现有登录控制器的逻辑,最合适的添加状态校验的位置是在用户认证成功之后——也就是Auth::attempt($credentials)通过的瞬间,这时候我们已经能拿到用户实例,立刻检查status字段就能及时拦截禁用账号的登录请求。

具体修改思路:

  1. 在用户认证成功后,立即获取当前用户实例
  2. 检查用户的status值,若为0则执行注销并返回禁用提示
  3. 保留原有其他业务逻辑,确保正常账号的登录流程不受影响

以下是修改后的完整登录控制器代码:

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:26:42