|
@@ -0,0 +1,280 @@
|
|
|
+<?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 PsyUserVerify
|
|
|
+{
|
|
|
+ const USER_DATA_URL = "/api.php";
|
|
|
+ /**
|
|
|
+ * Handle an incoming request.
|
|
|
+ *
|
|
|
+ * @param \Illuminate\Http\Request $request
|
|
|
+ * @param \Closure $next
|
|
|
+ * @return mixed
|
|
|
+ */
|
|
|
+ public function handle($request, Closure $next)
|
|
|
+ {
|
|
|
+ $validator = Validator::make($request->all(), [
|
|
|
+ 'appid' => 'required',
|
|
|
+ 'open_id' => 'required',
|
|
|
+ 'op' => 'required',
|
|
|
+ 'task' => 'required',
|
|
|
+ ], [
|
|
|
+ 'appid.required' => 'appid参数不能为空',
|
|
|
+ 'open_id.required' => 'open_id参数不能为空',
|
|
|
+ 'op.required' => 'op参数不能为空',
|
|
|
+ 'task.required' => 'task参数不能为空',
|
|
|
+ ]);
|
|
|
+
|
|
|
+ if ($validator->fails()) {
|
|
|
+ $msg = $validator->errors()->first();
|
|
|
+ return response()->json([
|
|
|
+ 'code'=>400,
|
|
|
+ 'msg'=>$msg
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+
|
|
|
+ $sign = $request->input("sign");
|
|
|
+ $signData = $request->only(array("appid","open_id","op", "task","version"));
|
|
|
+ $paramsData = $request->except(array("appid","op", "task","version","sign"));
|
|
|
+ $config = config("console.wg_map");
|
|
|
+ if ($config["appid"] != $signData["appid"]){
|
|
|
+ throw new \Exception("appid非法参数:{$signData["appid"]}");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (Admin::guard()->check() && Admin::user()->third_openid == $signData["open_id"]){
|
|
|
+ return next($request);
|
|
|
+ }
|
|
|
+ $nowSign=$this->getSign(
|
|
|
+ $paramsData,
|
|
|
+ $signData["op"],
|
|
|
+ $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();
|
|
|
+
|
|
|
+
|
|
|
+ if($checkUserData) {
|
|
|
+ Admin::guard()->login(
|
|
|
+ $checkUserData
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ return $next($request);
|
|
|
+ }
|
|
|
+
|
|
|
+ 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 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 = "login", 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){
|
|
|
+ $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;
|
|
|
+ }
|
|
|
+}
|