基于 ThinkPHP5.1 實現的海豚后臺登錄源碼分析

基于 thinkphp5.1 實現的海豚后臺登錄源碼分析

一、 首先來到登錄代碼處,部分代碼截圖,大家有興趣可以自己去看源碼

登錄處開始

public?function?signin() { ????if?($this->request->isPost())?{ ????????//?獲取post數據 ????????$data?=?$this->request->post();??? ????????$rememberme?=?isset($data['remember-me'])???true?:?false; ????????//?登錄鉤子,?做一些登錄前動作,?這里暫時沒有實現 ????????$hook_result?=?Hook::listen('signin',?$data); ????????if?(!empty($hook_result)?&&?true?!==?$hook_result[0])?{ ????????????$this->error($hook_result[0]); ????????} ????????//?驗證數據? ????????$result?=?$this->validate($data,?'User.signin'); ????????if(true?!==?$result){ ????????????//?驗證失敗?輸出錯誤信息 ????????????$this->error($result); ????????} ????????//?驗證碼?? ????????if?(config('captcha_signin'))?{ ????????????$captcha?=?$this->request->post('captcha',?''); ????????????$captcha?==?''?&&?$this->error('請輸入驗證碼'); ????????????if(!captcha_check($captcha,?'')){ ????????????????//驗證失敗 ????????????????$this->error('驗證碼錯誤或失效'); ????????????}; ????????} ????????//?登錄 ????????$UserModel?=?new?UserModel模型分析;???//?進去模型邏輯 ????????$uid?=?$UserModel->login($data['username'],?$data['password'],?$rememberme); ????????if?($uid)?{ ????????????//?記錄行為 ????????????action_log('user_signin',?'admin_user',?$uid,?$uid); ????????????$this->jumpUrl(); ????????}?else?{ ????????????$this->error($UserModel->getError()); ????????} ????}?else?{???//?下面是單點登錄的鉤子,目前后臺不支持 ?????????$hook_result?=?Hook::listen('signin_sso'); ??????????if?(!empty($hook_result)?&&?true?!==?$hook_result[0])?{ ??????????????if?(isset($hook_result[0]['url']))?{ ??????????????????$this->redirect($hook_result[0]['url']); ??????????????}??if?(isset($hook_result[0]['error']))?{ ??????????????????$this->error($hook_result[0]['error']); ?????????????}?} ??????????if?(is_signin())?{ ??????????$this->jumpUrl(); ?????????}?else?{ ??????????return?$this->fetch(); ?????????}} }

進入 UserModel 模型分析

$UserModel?=?new?UserModel;??? //?調用模型中的Login登錄,?賬號?密碼?是否記住我 $uid?=?$UserModel->login($data['username'],?$data['password'],?$rememberme); public?function?login($username?=?'',?$password?=?'',?$rememberme?=?false) { $username?=?trim($username);? $password?=?trim($password); //?匹配登錄方式 if?(preg_match("/^([a-zA-Z0-9_.-])+@(([a-zA-Z0-9-])+.)+([a-zA-Z0-9]{2,4})+$/",?$username))?{ //?郵箱登錄 $map['email']?=?$username; }?elseif?(preg_match("/^1d{10}$/",?$username))?{ //?手機號登錄 $map['mobile']?=?$username; }?else?{ //?用戶名登錄 $map['username']?=?$username; } $map['status']?=?1; //?查找用戶 $user?=?$this::get($map); if?(!$user)?{ $this->error?=?'用戶不存在或被禁用!'; }?else?{ //?檢查是否分配用戶組 if?($user['role']?==?0)?{ $this->error?=?'禁止訪問,原因:未分配角色!'; return?false; }??//?檢查是可登錄后臺 if?(!RoleModel::where(['id'?=>?$user['role'],?'status'?=>?1])->value('access'))?{ $this->error?=?'禁止訪問,用戶所在角色未啟用或禁止訪問后臺!'; return?false; }??if?(!Hash::check((string)$password,?$user['password']))?{ $this->error?=?'賬號或者密碼錯誤!'; }?else?{ $uid?=?$user['id']; //?更新登錄信息 $user['last_login_time']?=?request()->time(); $user['last_login_ip']???=?request()->ip(1); if?($user->save())?{ //?自動登錄 return?$this->autoLogin($this::get($uid),?$rememberme); }?else?{ //?更新登錄信息失敗 $this->error?=?'登錄信息更新失敗,請重新登錄!'; return?false; }?}?}??return?false; }

檢查各種權限沒有問題后開始登錄

立即學習PHP免費學習筆記(深入)”;

public?function?autoLogin($user,?$rememberme?=?false) { ????//?記錄登錄SESSION和COOKIES ????$auth?=?array( ????????'uid'?????????????=>?$user->id, ????????'group'???????????=>?$user->group, ????????'role'????????????=>?$user->role, ????????'role_name'???????=>?Db::name('admin_role')->where('id',?$user->role)->value('name'), ????????'avatar'??????????=>?$user->avatar, ????????'username'????????=>?$user->username, ????????'nickname'????????=>?$user->nickname, ????????'last_login_time'?=>?$user->last_login_time, ????????'last_login_ip'???=>?get_client_ip(1), ????); ????session('user_auth',?$auth);???//?默認保存session? ????session('user_auth_sign',?data_auth_sign($auth));??//參數進行加密 ????//?保存用戶節點權限,?方面后期直接用 ????if?($user->role?!=?1)?{ ????????$menu_auth?=?Db::name('admin_role')->where('id',?session('user_auth.role'))->value('menu_auth'); ????????$menu_auth?=?json_decode($menu_auth,?true); ????????if?(!$menu_auth)?{ ????????????session('user_auth',?null); ????????????session('user_auth_sign',?null); ????????????$this->error?=?'未分配任何節點權限!'; ????????????return?false; ????????} ????} ????//?記住登錄 ????if?($rememberme)?{???//?存儲的cookie??data_auth_sign?對signin?進行加密 ????????$signin_token?=?$user->username.$user->id.$user->last_login_time; ????????cookie('uid',?$user->id,?24?*?3600?*?7); ????????cookie('signin_token',?data_auth_sign($signin_token),?24?*?3600?*?7); ????} ????return?$user->id;???//登錄成功返回uid? }

關于 data_auth_sign 加密方法

?function?data_auth_sign($data?=?[]) { ????//?數據類型檢測 ????if(!is_array($data)){ ????????$data?=?(array)$data; ????} ????//?排序 ????ksort($data); ????//?url編碼并生成query字符串 ????$code?=?http_build_query($data); ????//?生成簽名 ????$sign?=?sha1($code); ????return?$sign; } 登錄后進行登錄行為記錄,大家可以根據自己需求選擇是否記錄 最后進行登陸后跳轉,分析用戶可以跳轉的?url private?function?jumpUrl() { ????if?(session('user_auth.role')?==?1)?{??//?判斷是否管理員 ????????$this->success('登錄成功',?url('admin/index/index')); ????} ????//?是否有指定默認跳轉模塊 ????$default_module?=?RoleModel::where('id',?session('user_auth.role'))->value('default_module'); ????$menu?=?MenuModel::get($default_module); ????if?(!$menu)?{ ????????$this->error('當前角色未指定默認跳轉模塊!'); ????} ????if?($menu['url_type']?==?'link')?{ ????????$this->success('登錄成功',?$menu['url_value']); ????} ????$menu_url?=?explode('/',?$menu['url_value']); ????role_auth(); ????$url?=?action('admin/ajax/getSidebarMenu',?['module_id'?=>?$default_module,?'module'?=>?$menu['module'],?'controller'?=>?$menu_url[1]]); ????if?($url?==?'')?{ ????????$this->error('權限不足'); ????}?else?{ ????????$this->success('登錄成功',?$url); ????} }

? 版權聲明
THE END
喜歡就支持一下吧
點贊12 分享