AuthProxy/go-back.php

205 lines
7.8 KiB
PHP
Raw Normal View History

2024-08-09 17:43:48 +08:00
<?php
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
use Workerman\Connection\AsyncTcpConnection;
use Workerman\Protocols\Http\Request;
use Workerman\Protocols\Http\Response as WebmanResponse;
use yzh52521\EasyHttp\Http;
use yzh52521\EasyHttp\Response;
use yzh52521\EasyHttp\RequestException;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker('http://0.0.0.0:8686');
function encryptAES($data, $key, $iv) {
$encrypted = openssl_encrypt($data, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
$encrypted = base64_encode($encrypted);
return $encrypted;
}
function decryptAES($encryptedData, $key, $iv) {
$encryptedData = base64_decode($encryptedData);
$decrypted = openssl_decrypt($encryptedData, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
return $decrypted;
}
function replaceHost($data,$host)
{
return preg_replace('/Host: (.*)/i','Host: '.$host,$data);
}
function HTMLview($filePath, $data) {
ob_start();
extract($data);
include $filePath;
$str = ob_get_contents();
ob_end_clean();
return $str;
}
$worker->onMessage = function(TcpConnection $connection, Request $data)
{
$config=json_decode(file_get_contents("./config.json"));
$matched=false;
foreach($config->website as $website){
if($website->query==$data->host(true)){
$config->website=$website;
$c_provider=$website->provider;
$config->provider=$config->provider->$c_provider;
$matched=true;
break;
}
}
if($matched==false){
$connection->send(HTMLview('./view/404.php', array()));
$connection->close();
}else{
$tWT = $data->cookie('WT', 'null');
if($tWT!='null'){
$key = 'laysensechina000';
$iv = '1234567890abcdef';
$wt=json_decode(decryptAES($tWT, $key, $iv));
if(time()-$wt->time<60){
$tWT=='null';
}
}
if($tWT=='null'){
if(strpos( $data->path(), "/login" ) === 0){
if( $data->path()=='/login/qywx/' ){
$code = $data->get('code','null');
if($code=='null'){
$connection->send(HTMLview('./view/login.php', array('public'=>$config->website->public,'website'=>$config->website,'provider'=>$config->provider,'special'=>'failed','uri'=>'/')));
$connection->close();
}else{
$http = new Workerman\Http\Client();
$tokenfile='./'.$config->website->api->qywx->appid.'.'.$config->website->api->qywx->agentid.'.token';
echo $tokenfile;
if(file_exists($tokenfile)){
$tokencontent=json_decode(file_get_contents($tokenfile));
$fulltoken=$tokencontent->token;
$ddl=$tokencontent->ddl;
if($ddl-time()<180){
$reapply=true;
}else{
$reapply=false;
}
}else{
$reapply=true;
}
if($reapply==true){
$apply=$response = Http::get('https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid='.$config->website->api->qywx->appid.'&corpsecret='.$config->website->api->qywx->token)->json();
$fulltoken=$apply->access_token;
$ddl=time()+$apply->expires_in;
$file=fopen($tokenfile,"w");
fwrite($file, json_encode(array('token'=>$fulltoken,'ddl'=>$ddl)));
fclose($file);
}
$lookup= Http::get('https://qyapi.weixin.qq.com/cgi-bin/auth/getuserinfo?access_token='.$fulltoken.'&code='.$code)->json();
if($lookup->errcode!=0){
$connection->send(HTMLview('./view/login.php', array('public'=>$config->website->public,'website'=>$config->website,'provider'=>$config->provider,'special'=>'failed','uri'=>'/')));
$connection->close();
}else{
$userid=$lookup->userid;
$userinfo=Http::get('https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token='.$fulltoken.'&userid='.$userid)->json();
$username=$userinfo->name;
$userposition=$userinfo->position;
$WT=json_encode(['id'=>$userid,'name'=>$username,'position'=>$userposition,'time'=>time()]);
$key = 'laysensechina000';
$iv = '1234567890abcdef';
$WT = encryptAES($WT, $key, $iv);
$dest=$data->get('jump','/');
$response = new WebmanResponse(200, [], HTMLview('./view/jump.php', array('website'=>$config->website,'provider'=>$config->provider,'userinfo'=>$userinfo,'dest'=>$dest)));
$response->cookie('WT', $WT,time()+9600,'/','.laysense.cn');
$connection->send($response);
$connection->close();
}
}
}
}else{
$connection->send(HTMLview('./view/login.php', array('public'=>$config->website->public,'website'=>$config->website,'provider'=>$config->provider,'special'=>null,'uri'=>$data->uri())));
$connection->close();
}
}else{
// Parse http header.
list($method, $addr, $http_version) = explode(' ', $data);
$_headers=explode("\r\n",$data);
$headers=[];
foreach ($_headers as $_header){
$_point=strpos($_header,':');
if ($_point===false) continue;
$headers[substr($_header,0,$_point)]=trim(trim(substr($_header,$_point),':'));
}
//源站IP地址
$source_ip=$config->website->ip;
$port=$config->website->port;
$source_host=$config->website->host;
$ssl=$config->website->ssl;
print_r('用户IP'.$data->header('X-Real-IP','127.0.0.1').'| 访问路径:'.$data->host().$data->uri() .' 源站:'.$source_ip.':'.$port.'| 回源域名'.$source_host.'|SSL:'.$ssl);
if($ssl==true){
$source_ip=$source_host;
}
// Async TCP connection.
$remote_connection = new AsyncTcpConnection('tcp://'.$source_ip.':'.$port);
// CONNECT.
if($ssl==true){
$remote_connection->transport = 'ssl';
}
if ($method !== 'CONNECT') {
//替换request 中的回源host
$remote_connection->send(replaceHost($data,$source_host));
// POST GET PUT DELETE etc.
} else {
$connection->send("HTTP/1.1 200 Connection Established\r\n\r\n");
}
$remote_connection->onMessage=function (TcpConnection $SourceConn, $SourceData)use ($connection){
$connection->send($SourceData);
};
$remote_connection->onClose = function ($source) use ($connection) {
$connection->close();
};
$remote_connection->onBufferFull = function ($SourceConn) use ($connection) {
$connection->pauseRecv();
};
$remote_connection->onBufferDrain = function ($SourceConn) use ($connection) {
$connection->resumeRecv();
};
$connection->onMessage=function (TcpConnection $ClientConn, $ClientData)use ($remote_connection,$source_host){
$remote_connection->send(replaceHost($ClientData,$source_host));
};
$connection->onClose = function (TcpConnection $ClientConn) use ($remote_connection) {
$remote_connection->close();
};
$connection->onBufferFull = function (TcpConnection $ClientConn) use ($remote_connection) {
$remote_connection->pauseRecv();
};
$connection->onBufferDrain = function (TcpConnection $ClientConn) use ($remote_connection) {
$remote_connection->resumeRecv();
};
$remote_connection->connect();
}
}
};
// 运行worker
Worker::runAll();