123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348 |
- <?php
- namespace App\Http\Middleware;
- use Closure;
- use Encore\Admin\Facades\Admin;
- use Illuminate\Log\Logger;
- use Illuminate\Support\Facades\DB;
- use Illuminate\Support\Facades\Log;
- use Illuminate\Support\Facades\Redis;
- use Illuminate\Support\Facades\Validator;
- use Monolog\Handler\RotatingFileHandler;
- //站点用户验证
- class PsyUserSso
- {
- const USER_DATA_URL = "/api.php";
- private $url = "/admin/ssoIndex";
- /**
- * Handle an incoming request.
- *
- * @param \Illuminate\Http\Request $request
- * @param \Closure $next
- * @return mixed
- */
- public function handle($request, Closure $next)
- {
- if (Admin::guard()->check()){
- return $next($request);
- }
- $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","go_url"));
- $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 $next($request);
- }
-
- $userData = $this->getUserData($signData["open_id"]);//下面需要获取用户账号、昵称、头像
- // $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")
- )
- );
- }
- }
- }
- DB::commit();
- Admin::guard()->login(
- $checkUserData
- );
- auth('admin')->login(
- $checkUserData
- );
- // echo 'aaaaaaa';exit;
- $key = "RemoteSso:".$_SERVER['HTTP_HOST'].":".$checkUserData->id;
- Redis::SET($key, true);
- $goUrl = $signData['go_url'] ?: $this->url;
- // Log::info("登录成功",[$checkUserData->id,$checkUserData->username, $goUrl]);
- return $next($request);
- }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 getSign(array $sendData, string $op = "user", string $task = "login", 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 getSsoSign(array $data)
- {
- $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. $str. $secret);
- return $sign;
- }
- /**
- * 得到结果数据
- * @param string $resultStr
- * @return mixed
- * @throws \Exception
- */
- private function getResult(string $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"];
- }
- 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;
- }
- }
|