"loginOther", * "appid"=>"iog+hayCB57Kuo4lyuKWZQ==", * "open_id"=>"e//z3xernIiOmHQIqORkBw==", * "version"=>"1.0.0", * "sign"=>"a6f1e87dd1b21109e36241c1468a638e" * )) * ); * @param Request $request * @param Request $response * @return mixed * @throws \Exception */ public function verifyVisitApi(Request $request,Response $response) { $sign = $request->get("sign"); $signData = $request->only(array("task","appid","open_id","version","go_url")); $config = config("console.remote_sso"); if ($config["appid"] != $signData["appid"]){ throw new \Exception("appid非法参数:{$signData["appid"]}"); } if (Admin::guard()->check() && Admin::user()->third_openid == $signData["open_id"]){ return $this->redirect($this->url,"登录成功"); } $nowSign=$this->getSign( array("open_id"=>$signData["open_id"]), "core", $signData["task"], $signData["version"] ); if ($nowSign != $sign){ throw new \Exception("签名验证不能通过:sign:{$sign}、nowSign:{$nowSign}"); } $userModelClass = config('admin.database.users_model'); $userModel = new $userModelClass(); $checkUserData = $userModel::query() ->where( array( "third_openid"=>$signData["open_id"] ) ) ->orderBy("id","desc")->first(); try { DB::beginTransaction(); $plaintext = ""; $defaultPassword = ""; if (!empty($checkUserData)){ $plaintext = "{$checkUserData->username}@123456"; $defaultPassword = bcrypt($plaintext); } if (empty($checkUserData)){ //开始菜单授权 $permissionModelClass = config('admin.database.permissions_model'); $roleModelClass = config('admin.database.roles_model'); $userAvatar = config('admin.default_avatar'); $name = "";//名称 $userName="";//登录账号 $userData = $this->getUserData($signData["open_id"]);//下面需要获取用户账号、昵称、头像 if (isset($userData["user"])){ if (isset($userData["user"]["name"])){ $name = $userData["user"]["name"]; } $name = empty($name)?$userData["user"]["username"]:$name; $userName = $userData["user"]["username"]; } $plaintext = "{$userName}@123456"; $defaultPassword = bcrypt($plaintext); $checkUserData = $userModel->create(array( "username"=>$userName, "password"=>$defaultPassword, "name"=>$name, "avatar"=>null, )); if (empty($checkUserData)){ throw new \RuntimeException("新增用户信息失败"); } DB::table($userModel::query()->getModel()->getTable())->where( array("id"=>$checkUserData->id) )->update(array( "third_openid"=>$signData["open_id"] )); $roleSlugName = array("RemoteSso");//角色名称 slug $permissionsSlugName = array("RemoteSso");//权限名称 slug $permissionModel = new $permissionModelClass(); $roleModel = new $roleModelClass(); foreach ($roleSlugName as $val){ $roleData = $roleModel::query() ->where( array( "slug"=>$val ) ) ->orderBy("id","desc")->first(); if (!empty($roleData)){ DB::table("admin_role_users")->insert( array( "role_id"=>$roleData->id, "user_id"=>$checkUserData->id, "created_at"=>date("Y-m-d H:i:s") ) ); } } foreach ($permissionsSlugName as $val){ $permissionData = $permissionModel::query() ->where( array( "slug"=>$val ) ) ->orderBy("id","desc")->first(); if (!empty($permissionData)){ DB::table("admin_user_permissions")->insert( array( "permission_id"=>$permissionData->id, "user_id"=>$checkUserData->id, "created_at"=>date("Y-m-d H:i:s") ) ); } } } // if ($defaultPassword != $checkUserData->password){ // $checkUserData->update(array("password"=>$defaultPassword)); // } DB::commit(); Admin::guard()->login( $checkUserData ); $key = "RemoteSso:".$_SERVER['HTTP_HOST'].":".$checkUserData->id; Redis::SET($key, true); return $this->redirect($this->url,"登录成功"); }catch (\Exception $exception){ Log::error("远程授权登录出错",[$exception->getMessage(),$exception->getTrace()]); DB::rollBack(); return "登录失败"; } } public function verifyVisitUrl(Request $request,Response $response) { $sign = $request->get("sign"); $signData = $request->only(array("task","appid","open_id","version","go_url")); $config = config("console.remote_sso"); if ($config["appid"] != $signData["appid"]){ throw new \Exception("appid非法参数:{$signData["appid"]}"); } $paramsData = $request->except(array("appid","op", "task","version","sign")); $userModelClass = config('admin.database.users_model'); $userModel = new $userModelClass(); if (Admin::guard()->check() && Admin::user()->third_openid == $signData["open_id"]){ //更新用户信息 $res = DB::table($userModel::query()->getModel()->getTable())->where( array("id"=>Admin::user()->id) )->update(array( "third_openid"=>$signData["open_id"], "workstation_id"=>$paramsData['outside_c_id'], "workstation_name"=>$paramsData['visit_title'] )); return $this->redirect($this->url,"登录成功"); } $nowSign=$this->getSign( $paramsData, "core", $signData["task"], $signData["version"] ); if ($nowSign != $sign){ throw new \Exception("签名验证不能通过:sign:{$sign}、nowSign:{$nowSign}"); } $checkUserData = $userModel::query() ->where( array( "third_openid"=>$signData["open_id"], ) ) ->orderBy("id","desc")->first(); try { DB::beginTransaction(); $plaintext = ""; $defaultPassword = ""; if (!empty($checkUserData)){ $plaintext = "{$checkUserData->username}@123456"; $defaultPassword = bcrypt($plaintext); } if (empty($checkUserData)){ //开始菜单授权 $permissionModelClass = config('admin.database.permissions_model'); $roleModelClass = config('admin.database.roles_model'); $userAvatar = config('admin.default_avatar'); $name = "";//名称 $userName="";//登录账号 $userData = $this->getUserData($signData["open_id"]);//下面需要获取用户账号、昵称、头像 if (isset($userData["user"])){ if (isset($userData["user"]["name"])){ $name = $userData["user"]["name"]; } $name = empty($name)?$userData["user"]["username"]:$name; $userName = $userData["user"]["username"]; } $plaintext = "{$userName}@123456"; $defaultPassword = bcrypt($plaintext); $checkUserData = $userModel->create(array( "username"=>$userName, "password"=>$defaultPassword, "name"=>$name, "avatar"=>null, )); if (empty($checkUserData)){ throw new \RuntimeException("新增用户信息失败"); } DB::table($userModel::query()->getModel()->getTable())->where( array("id"=>$checkUserData->id) )->update(array( "third_openid"=>$signData["open_id"], "workstation_id"=>$paramsData['outside_c_id'], "workstation_name"=>$paramsData['visit_title'] )); $roleSlugName = array("RemoteSso");//角色名称 slug $permissionsSlugName = array("RemoteSso");//权限名称 slug $permissionModel = new $permissionModelClass(); $roleModel = new $roleModelClass(); foreach ($roleSlugName as $val){ $roleData = $roleModel::query() ->where( array( "slug"=>$val ) ) ->orderBy("id","desc")->first(); if (!empty($roleData)){ DB::table("admin_role_users")->insert( array( "role_id"=>$roleData->id, "user_id"=>$checkUserData->id, "created_at"=>date("Y-m-d H:i:s") ) ); } } foreach ($permissionsSlugName as $val){ $permissionData = $permissionModel::query() ->where( array( "slug"=>$val ) ) ->orderBy("id","desc")->first(); if (!empty($permissionData)){ DB::table("admin_user_permissions")->insert( array( "permission_id"=>$permissionData->id, "user_id"=>$checkUserData->id, "created_at"=>date("Y-m-d H:i:s") ) ); } } } // if ($defaultPassword != $checkUserData->password){ // $checkUserData->update(array("password"=>$defaultPassword)); // } DB::commit(); Admin::guard()->login( $checkUserData ); $key = "RemoteSso:".$_SERVER['HTTP_HOST'].":".$checkUserData->id; Redis::SET($key, true); return $this->redirect($this->url,"登录成功"); }catch (\Exception $exception){ Log::error("远程授权登录出错",[$exception->getMessage(),$exception->getTrace()]); DB::rollBack(); return "登录失败"; } } public function getUserData(string $openId) { if (empty($openId)){ throw new \Exception("openId不能为空"); } $config = config("console.remote_sso"); $url = $config["url"].self::USER_DATA_URL;//http://www.baidu.com/api.php $query = array( "op"=>"user", "task"=>"userData", "version"=>"1.0.0", "appid"=>$config["appid"] ); $sendData = array( "open_id"=>$openId ); $postData = $sendData; $query["sign"] = $this->getSign($postData,$query["op"],$query["task"],$query["version"]); // $client = new Client(); $url = $url."?".http_build_query($query); $resultStr = $this->curlPost($url,$postData); // $response = $client->request('post', $url, [ // 'query' => $query, // "headers"=>array( // "Content-type"=>"application/json" // ), // "form_params"=>$postData // ]); // $resultStr = $response->getBody()->getContents(); return $this->getResult($resultStr); } public function getChildWorksation(string $openOcId) { if (empty($openOcId)){ throw new \Exception("openOcId不能为空"); } $config = config("console.wg_map"); $url = $config["url"].self::USER_DATA_URL;//http://www.baidu.com/api.php $query = array( "op"=>"visit", "task"=>"getDownCompanyDatas", "version"=>"1.0.0", "appid"=>$config["appid"] ); $sendData = array( "open_oc_id"=>$openOcId, 's_timestamp' => time(), ); $postData = $sendData; $query["sign"] = $this->getWgSign($postData,$query["op"],$query["task"],$query["version"]); // $client = new Client(); $url = $url."?".http_build_query($query); $resultStr = $this->curlPost($url,$postData); // $response = $client->request('post', $url, [ // 'query' => $query, // "headers"=>array( // "Content-type"=>"application/json" // ), // "form_params"=>$postData // ]); // $resultStr = $response->getBody()->getContents(); return $this->getResult($resultStr); } public function getUserMenuWebsiteData(string $openId) {$config = config("console.remote_sso"); $url = $config["url"].self::USER_DATA_URL;//http://www.baidu.com/api.php $query = array( "op"=>"menu", "task"=>"getMenu", "version"=>"1.0.0", "appid"=>$config["appid"] ); $sendData = array( "open_id"=>$openId ); $query["sign"] = $this->getSign($sendData,$query["op"],$query["task"],$query["version"]); // $client = new Client(); // $response = $client->request('post', $url, [ // 'query' => $query, // "headers"=>array( // "Content-type"=>"application/json" // ), // "form_params"=>$sendData // ]); // $resultStr = $response->getBody()->getContents(); $url = $url."?".http_build_query($query); $resultStr = $this->curlPost($url,$sendData); return $this->getResult($resultStr); } public function getSign(array $sendData, string $op = "user", string $task = "getUserInfo", string $version = "1.0.0") { $config = config("console.remote_sso"); $appid = $config["appid"]; $secret = $config["secret"]; ksort($sendData); $str = ""; foreach($sendData as $key =>$value){ $str.= stripslashes($value); } $sign = md5($appid. $op . $task . $version . $str. $secret); return $sign; } public function getWgSign(array $sendData, string $op = "user", string $task = "getUserInfo", string $version = "1.0.0") { $config = config("console.wg_map"); $appid = $config["appid"]; $secret = $config["secret"]; ksort($sendData); $str = ""; foreach($sendData as $key =>$value){ $str.= stripslashes($value); } $sign = md5($appid. $op . $task . $version . $str. $secret); return $sign; } /** * 得到结果数据 * @param string $resultStr * @return mixed * @throws \Exception */ private function getResult(string $resultStr){ $this->log("返回值",$resultStr); $result = json_decode($resultStr,true); if (json_last_error() !== JSON_ERROR_NONE) { $this->log("数据格式响应错误",$resultStr); throw new \Exception("数据格式响应错误".$resultStr); } if (empty($result["status"])){ $content = $result["message"] ?? $resultStr; $this->log("结果信息发生错误",$content); throw new \Exception("结果信息发生错误".$content); } if (!isset($result["data"])){ $content = $resultStr; $this->log("结果信息格式发送错误",$content); throw new \Exception("结果信息格式发送错误".$content); } return $result["data"]; } /** * @param string $msg 消息提示 * @param array|string|object $content 结果内容 * @return void */ private function log(string $msg,$content) { $sqlFile = 'logs/remoteSso/info.log'; (new Logger('remoteSso'))->pushHandler(new RotatingFileHandler(storage_path($sqlFile)))->info($msg,[$content]); } private function curlPost($url, $data=null, $file=null) { $ch = curl_init($url); curl_setopt($ch, CURLOPT_TIMEOUT, 60); //设置超时 // if(!empty($file)){ // foreach ($file as $k=>$v){ // if(is_array($v)){ // //多个文件 // foreach ($v as $key=>$val){ // $data[$k.'['.$key.']'] = new CURLFile($val); // } // }else{ // //一维 // $data[$k] = new CURLFile($v); // } // } // } if (0 === strpos(strtolower($url), "https")) { curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); //对认证证书来源的检查 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); //从证书中检查SSL加密算法是否存在 } curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // curl_setopt($ch, CURLOPT_HTTPHEADER); $rtn = curl_exec($ch);//CURLOPT_RETURNTRANSFER 不设置 curl_exec返回TRUE 设置 curl_exec返回json(此处) 失败都返回FALSE curl_close($ch); return $rtn; } /** * json 形式传参 * @param unknown $url * @param unknown $data */ private function curlPostJson($url, $data = null) { $headers = array( "Content-type: application/json;charset='utf-8'", "Accept: application/json", "Cache-Control: no-cache", "Pragma: no-cache", ); $ch = curl_init($url); curl_setopt($ch, CURLOPT_TIMEOUT, 60); //设置超时 if (0 === strpos(strtolower($url), "https")) { curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); //对认证证书来源的检查 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); //从证书中检查SSL加密算法是否存在 } curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_HEADER, 1);//打印响应header $rtn = curl_exec($ch);//CURLOPT_RETURNTRANSFER 不设置 curl_exec返回TRUE 设置 curl_exec返回json(此处) 失败都返回FALSE $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE); // 根据头大小去获取头信息内容 $header = substr($rtn, 0, $header_size); $data = substr($rtn, $header_size); $is_gzipped = false; if (preg_match("/Content-Encoding: gzip/", $header)) { $is_gzipped = true; } if($is_gzipped){ $data = gzdecode($data); } curl_close($ch); return $data; } /** * @param string $targetUrl * @param string $msg * @param int $wait 跳转时间 * @return string */ private function redirect($targetUrl,$msg,$wait = 3) { return <<
$msg,正在跳转,请稍候...