123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608 |
- <?php
- namespace App\Repositories\Eloquent;
- use App\Repositories\Contracts\RemoteSsoInterface;
- use Encore\Admin\Facades\Admin;
- use GuzzleHttp\Client;
- use Illuminate\Http\Request;
- use Illuminate\Http\Response;
- use Illuminate\Support\Facades\DB;
- use Illuminate\Support\Facades\Log;
- use Monolog\Handler\RotatingFileHandler;
- use Monolog\Logger;
- use Illuminate\Support\Facades\Redis;
- /**
- * 远程授权登录相关操作
- */
- class RemoteSsoFacadeRepository extends BaseRepository implements RemoteSsoInterface
- {
- private $url = "/admin/ssoIndex";
- /**
- * http://bj.zy.com/admin/remoteSso?task=loginOther&appid=iog%2BhayCB57Kuo4lyuKWZQ%3D%3D&open_id=e%2F%2Fz3xernIiOmHQIqORkBw%3D%3D&version=1.0.0&sign=a6f1e87dd1b21109e36241c1468a638e
- * dd(
- * http_build_query(array(
- * "task"=>"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 <<<HTML
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>跳转中...</title>
- <style>
- body {
- font-family: Arial, sans-serif;
- background-color: #f4f4f4;
- margin: 0;
- padding: 0;
- display: flex;
- justify-content: center;
- align-items: center;
- height: 100vh;
- }
- .container {
- text-align: center;
- background-color: #ffffff;
- padding: 20px;
- border-radius: 8px;
- box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
- }
- p {
- margin-bottom: 10px;
- color: #333333;
- }
- .loader {
- border: 4px solid #f3f3f3;
- border-top: 4px solid #3498db;
- border-radius: 50%;
- width: 20px;
- height: 20px;
- animation: spin 2s linear infinite;
- display: inline-block;
- margin-right: 10px;
- }
- @keyframes spin {
- 0% { transform: rotate(0deg); }
- 100% { transform: rotate(360deg); }
- }
- </style>
- </head>
- <body>
- <div class="container">
- <div class="loader"></div>
- <p>$msg,正在跳转,请稍候...</p>
- <meta http-equiv="refresh" content="$wait;url={$targetUrl}">
- <script type="text/javascript">
- // 如果浏览器不支持 meta 标签自动跳转,则使用 JavaScript 进行跳转
- setTimeout(function() {
- window.location.href = "{$targetUrl}";
- }, 3000);
- </script>
- </div>
- </body>
- </html>
- HTML;
- }
- }
|