diff --git a/app/Http/Controllers/Api/SystemController.php b/app/Http/Controllers/Api/SystemController.php index 8cc09fbb0..16515b77e 100755 --- a/app/Http/Controllers/Api/SystemController.php +++ b/app/Http/Controllers/Api/SystemController.php @@ -8,6 +8,7 @@ use App\Models\UserCheckinRecord; use App\Module\Base; use App\Module\BillExport; use App\Module\BillMultipleExport; +use App\Module\Doo; use App\Module\Extranet; use Arr; use Carbon\Carbon; @@ -536,7 +537,7 @@ class SystemController extends AbstractController 'ip-gcj02' => Extranet::getIpGcj02(Base::getIp()), 'ip-iscn' => Base::isCnIp(Base::getIp()), 'header' => Request::header(), - 'token' => Base::getToken(), + 'token' => Doo::userToken(), 'url' => url('') . Base::getUrl(), ]); } diff --git a/app/Http/Controllers/Api/UsersController.php b/app/Http/Controllers/Api/UsersController.php index 40a729087..dfb346031 100755 --- a/app/Http/Controllers/Api/UsersController.php +++ b/app/Http/Controllers/Api/UsersController.php @@ -131,7 +131,7 @@ class UsersController extends AbstractController ]; $user->updateInstance($array); $user->save(); - User::token($user); + User::generateToken($user); LdapUser::userSync($user, $password); // if (!Project::withTrashed()->whereUserid($user->userid)->wherePersonal(1)->exists()) { @@ -189,7 +189,7 @@ class UsersController extends AbstractController ]; $user->updateInstance($array); $user->save(); - User::token($user); + User::generateToken($user); return Base::retSuccess("success", $user); } // @@ -299,7 +299,7 @@ class UsersController extends AbstractController public function info() { $user = User::auth(); - User::token($user); + User::generateToken($user); // $data = $user->toArray(); $data['nickname_original'] = $user->getRawOriginal('nickname'); @@ -382,7 +382,7 @@ class UsersController extends AbstractController } // $user->save(); - User::token($user); + User::generateToken($user); LdapUser::userUpdate($user->email, $upLdap); // return Base::retSuccess('修改成功', $user); @@ -415,7 +415,7 @@ class UsersController extends AbstractController } User::passwordPolicy($newpass); // - $verify = User::whereUserid($user->userid)->wherePassword(Doo::md5s($oldpass, User::token2encrypt()))->count(); + $verify = User::whereUserid($user->userid)->wherePassword(Doo::md5s($oldpass, Doo::userEncrypt()))->count(); if (empty($verify)) { return Base::retError('请填写正确的旧密码'); } @@ -424,7 +424,7 @@ class UsersController extends AbstractController $user->password = Doo::md5s($newpass, $user->encrypt); $user->changepass = 0; $user->save(); - User::token($user); + User::generateToken($user); LdapUser::userUpdate($user->email, ['userPassword' => $newpass]); return Base::retSuccess('修改成功', $user); } @@ -1272,7 +1272,7 @@ class UsersController extends AbstractController $user->email = $newEmail; $user->save(); - User::token($user); + User::generateToken($user); return Base::retSuccess('修改成功', $user); } diff --git a/app/Http/Middleware/WebApi.php b/app/Http/Middleware/WebApi.php index cc6083e53..c66b3a1d6 100644 --- a/app/Http/Middleware/WebApi.php +++ b/app/Http/Middleware/WebApi.php @@ -32,7 +32,7 @@ class WebApi if (in_array(strtolower($APP_SCHEME), ['https', 'on', 'ssl', '1', 'true', 'yes'], true)) { $request->setTrustedProxies([$request->getClientIp()], $request::HEADER_X_FORWARDED_PROTO); } - Doo::init(); + Doo::load(); return $next($request); } diff --git a/app/Models/User.php b/app/Models/User.php index 27c80a00b..a10767c5d 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -283,9 +283,9 @@ class User extends AbstractModel if (!Base::isEmail($email)) { throw new ApiException('请输入正确的邮箱地址'); } - if (User::email2userid($email) > 0) { + $user = self::whereEmail($email)->first(); + if ($user) { $isRegVerify = Base::settingFind('emailSetting', 'reg_verify') === 'open'; - $user = self::whereUserid(User::email2userid($email))->first(); if ($isRegVerify && $user->email_verity === 0) { UserEmailVerification::userEmailSend($user); throw new ApiException('您的帐号已注册过,请验证邮箱', ['code' => 'email']); @@ -320,73 +320,6 @@ class User extends AbstractModel return $user->find($user->userid); } - /** - * 邮箱获取userid - * @param $email - * @return int - */ - public static function email2userid($email) - { - if (empty($email)) { - return 0; - } - return intval(self::whereEmail($email)->value('userid')); - } - - /** - * token获取会员userid - * @return int - */ - public static function token2userid() - { - return self::authFind('userid', Base::getToken()); - } - - /** - * token获取会员邮箱 - * @return int - */ - public static function token2email() - { - return self::authFind('email', Base::getToken()); - } - - /** - * token获取encrypt - * @return mixed|string - */ - public static function token2encrypt() - { - return self::authFind('encrypt', Base::getToken()); - } - - /** - * 获取token身份信息 - * @param $find - * @param null $token - * @return array|mixed|string - */ - public static function authFind($find, $token = null) - { - if ($token === null) { - $token = Base::getToken(); - } - list($userid, $email, $encrypt, $timestamp) = explode("#$", base64_decode($token) . "#$#$#$#$"); - $array = [ - 'userid' => intval($userid), - 'email' => $email ?: '', - 'encrypt' => $encrypt ?: '', - 'timestamp' => intval($timestamp), - ]; - if (isset($array[$find])) { - return $array[$find]; - } - if ($find == 'all') { - return $array; - } - return ''; - } - /** * 获取我的ID * @return int @@ -422,9 +355,15 @@ class User extends AbstractModel { $user = self::authInfo(); if (!$user) { - $authorization = Base::getToken(); - if ($authorization) { - throw new ApiException('身份已失效,请重新登录', [], -1); + if (Base::headerOrInput('token')) { + throw new ApiException('身份已失效,请重新登录', [ + 'token' => Base::headerOrInput('token'), + 'tokenDecode' => Doo::tokenDecode(Base::headerOrInput('token')), + 'userToken' => Doo::userToken(), + 'userId' => Doo::userId(), + 'userEmail' => Doo::userEmail(), + 'userEncrypt' => Doo::userEncrypt(), + ], -1); } else { throw new ApiException('请登录后继续...', [], -1); } @@ -448,61 +387,46 @@ class User extends AbstractModel if (isset($_A["__static_auth"])) { return $_A["__static_auth"]; } - $authorization = Base::getToken(); - if ($authorization) { - $authInfo = self::authFind('all', $authorization); - if ($authInfo['userid'] > 0) { - $loginValid = floatval(Base::settingFind('system', 'loginValid')) ?: 720; - $loginValid *= 3600; - if ($authInfo['timestamp'] + $loginValid > time() || $authInfo['timestamp'] === -1) { - $row = self::whereUserid($authInfo['userid'])->whereEmail($authInfo['email'])->whereEncrypt($authInfo['encrypt'])->first(); - if ($row) { - if (!$row->bot && $authInfo['timestamp'] === -1) { - return $_A["__static_auth"] = false; // 非机器人token时间不允许-1 - } - $upArray = []; - if (Base::getIp() && $row->line_ip != Base::getIp()) { - $upArray['line_ip'] = Base::getIp(); - } - if (Carbon::parse($row->line_at)->addSeconds(30)->lt(Carbon::now())) { - $upArray['line_at'] = Carbon::now(); - } - if ($upArray) { - $row->updateInstance($upArray); - $row->save(); - } - return $_A["__static_auth"] = $row; - } - } + if (Doo::userId() > 0 + && !Doo::userExpired() + && $user = self::whereUserid(Doo::userId())->whereEmail(Doo::userEmail())->whereEncrypt(Doo::userEncrypt())->first()) { + $upArray = []; + if (Base::getIp() && $user->line_ip != Base::getIp()) { + $upArray['line_ip'] = Base::getIp(); } + if (Carbon::parse($user->line_at)->addSeconds(30)->lt(Carbon::now())) { + $upArray['line_at'] = Carbon::now(); + } + if ($upArray) { + $user->updateInstance($upArray); + $user->save(); + } + return $_A["__static_auth"] = $user; } return $_A["__static_auth"] = false; } /** - * 生成token + * 生成 token * @param self $userinfo + * @param bool $force 获取新的token * @return string */ - public static function token($userinfo) + public static function generateToken($userinfo, $force = false) { - $time = $userinfo->bot ? -1 : time(); - $userinfo->token = base64_encode($userinfo->userid . '#$' . $userinfo->email . '#$' . $userinfo->encrypt . '#$' . $time . '#$' . Base::generatePassword(6)); + if (!$force && Doo::userId() == $userinfo->userid) { + $token = Doo::userToken(); + } else { + if ($userinfo->bot) { + $days = 0; + } else { + $days = max(1, intval(Base::settingFind('system', 'token_valid_days', 7))); + } + $token = Doo::tokenEncode($userinfo->userid, $userinfo->email, $userinfo->encrypt, $days); + } unset($userinfo->encrypt); unset($userinfo->password); - return $userinfo->token; - } - - /** - * 判断用户权限(身份) - * @param $identity - * @param $userIdentity - * @return bool - */ - public static function identityRaw($identity, $userIdentity) - { - $userIdentity = is_array($userIdentity) ? $userIdentity : explode(",", trim($userIdentity, ",")); - return $identity && in_array($identity, $userIdentity); + return $userinfo->token = $token; } /** @@ -536,8 +460,7 @@ class User extends AbstractModel */ public static function userid2nickname($userid) { - $basic = self::userid2basic($userid); - return $basic ? $basic->nickname : ''; + return self::userid2basic($userid)?->nickname ?: ''; } /** diff --git a/app/Module/Base.php b/app/Module/Base.php index 9961a4682..727315495 100755 --- a/app/Module/Base.php +++ b/app/Module/Base.php @@ -2019,29 +2019,6 @@ class Base return $array; } - /** - * 获取tonken - * @return string - */ - public static function getToken() - { - global $_A; - if (!isset($_A["__static_token"])) { - $_A["__static_token"] = self::headerOrInput('token'); - } - return $_A["__static_token"]; - } - - /** - * 设置tonken - * @param $token - */ - public static function setToken($token) - { - global $_A; - $_A["__static_token"] = $token; - } - /** * 是否微信 * @return bool diff --git a/app/Module/Doo.php b/app/Module/Doo.php index 55ba7cb1c..4197105f5 100644 --- a/app/Module/Doo.php +++ b/app/Module/Doo.php @@ -9,40 +9,39 @@ use FFI; class Doo { - public static $doo = null; - - public function __construct() - { - return self::init(); - } + private static $doo = null; + private static $token = null; + private static $language = null; /** - * 初始化 - * @return mixed + * 加载模块 + * @param $token + * @param $language + * @return null */ - public static function init() + public static function load($token = null, $language = null) { if (self::$doo === null) { - $doo = FFI::cdef(<<initialize("/var/www", Base::headerOrInput('language')); - $doo->setUserToken(Base::getToken()); - self::$doo = $doo; + EOF, app_path("Module/Lib/doo.so")); + self::$token = $token ?: Base::headerOrInput('token'); + self::$language = $language ?: Base::headerOrInput('language'); } + self::$doo->initialize("/var/www", self::$token, self::$language); return self::$doo; } @@ -51,7 +50,7 @@ class Doo * @param $text * @return string */ - public static function string($text) + private static function string($text) { return FFI::string($text); } @@ -62,7 +61,7 @@ class Doo */ public static function license() { - $array = Base::json2array(self::string(self::init()->license())); + $array = Base::json2array(self::string(self::load()->license())); $ips = explode(",", $array['ip']); $array['ip'] = []; @@ -98,7 +97,7 @@ class Doo */ public static function licenseDecode($license) { - return Base::json2array(self::string(self::init()->licenseDecode($license))); + return Base::json2array(self::string(self::load()->licenseDecode($license))); } /** @@ -108,7 +107,7 @@ class Doo */ public static function licenseSave($license) { - return (bool)self::init()->licenseSave($license); + return (bool)self::load()->licenseSave($license); } /** @@ -117,7 +116,7 @@ class Doo */ public static function userId() { - return self::init()->userId(); + return intval(self::load()->userId()); } /** @@ -126,7 +125,17 @@ class Doo */ public static function userExpired() { - return Carbon::parse(self::string(self::init()->userExpiredAt()))->isBefore(Carbon::now()); + $expiredAt = self::userExpiredAt(); + return $expiredAt != 'forever' && Carbon::parse($expiredAt)->isBefore(Carbon::now()); + } + + /** + * token过期时间(来自请求的token) + * @return bool + */ + public static function userExpiredAt() + { + return self::string(self::load()->userExpiredAt()); } /** @@ -135,7 +144,16 @@ class Doo */ public static function userEmail() { - return self::string(self::init()->userEmail()); + return self::string(self::load()->userEmail()); + } + + /** + * 当前会员Encrypt(来自请求的token) + * @return string + */ + public static function userEncrypt() + { + return self::string(self::load()->userEncrypt()); } /** @@ -144,7 +162,7 @@ class Doo */ public static function userToken() { - return self::string(self::init()->userToken()); + return self::string(self::load()->userToken()); } /** @@ -155,7 +173,7 @@ class Doo */ public static function userCreate($email, $password) { - $data = Base::json2array(self::string(self::init()->userCreate($email, $password))); + $data = Base::json2array(self::string(self::load()->userCreate($email, $password))); if (Base::isError($data)) { throw new ApiException($data['msg'] ?: '注册失败'); } @@ -176,7 +194,7 @@ class Doo */ public static function tokenEncode($userid, $email, $encrypt, $days = 7) { - return self::string(self::init()->tokenEncode($userid, $email, $encrypt, $days)); + return self::string(self::load()->tokenEncode($userid, $email, $encrypt, $days)); } /** @@ -186,9 +204,7 @@ class Doo */ public static function tokenDecode($token) { - $array = Base::json2array(self::string(self::init()->tokenDecode($token))); - $array['is_expired'] = Carbon::parse($array['expired_at'])->isBefore(Carbon::now()); - return $array; + return Base::json2array(self::string(self::load()->tokenDecode($token))); } /** @@ -199,7 +215,7 @@ class Doo */ public static function translate($text, $type = "") { - return self::string(self::init()->translate($text, $type)); + return self::string(self::load()->translate($text, $type)); } /** @@ -210,6 +226,6 @@ class Doo */ public static function md5s($text, $password = "") { - return self::string(self::init()->md5s($text, $password)); + return self::string(self::load()->md5s($text, $password)); } } diff --git a/app/Module/Lib/doo.h b/app/Module/Lib/doo.h index cc053d8b8..f8d4267b4 100644 --- a/app/Module/Lib/doo.h +++ b/app/Module/Lib/doo.h @@ -82,6 +82,7 @@ extern GoUint8 licenseSave(char* license); extern int userId(); extern char* userExpiredAt(); extern char* userEmail(); +extern char* userEncrypt(); extern char* userToken(); extern char* userCreate(char* email, char* password); extern char* tokenEncode(int userid, char* email, char* encrypt, int days); diff --git a/app/Module/Lib/doo.so b/app/Module/Lib/doo.so index c1453e103..f6afa2233 100644 Binary files a/app/Module/Lib/doo.so and b/app/Module/Lib/doo.so differ diff --git a/app/Services/WebSocketService.php b/app/Services/WebSocketService.php index 104429848..f03159606 100644 --- a/app/Services/WebSocketService.php +++ b/app/Services/WebSocketService.php @@ -8,6 +8,7 @@ use App\Models\User; use App\Models\WebSocket; use App\Models\WebSocketDialogMsg; use App\Module\Base; +use App\Module\Doo; use App\Tasks\LineTask; use App\Tasks\PushTask; use Cache; @@ -39,55 +40,44 @@ class WebSocketService implements WebSocketHandlerInterface */ public function onOpen(Server $server, Request $request) { - global $_A; - $_A = [ - '__static_langdata' => [], - ]; $fd = $request->fd; - $data = Base::newTrim($request->get); - $action = $data['action']; + $get = Base::newTrim($request->get); + $action = $get['action']; switch ($action) { /** * 网页访问 */ case 'web': { - // 判断token参数 - $token = $data['token']; - $cacheKey = "ws::token:" . md5($token); - $userid = Cache::remember($cacheKey, now()->addSeconds(1), function () use ($token) { - $authInfo = User::authFind('all', $token); - if ($authInfo['userid'] > 0) { - if (User::whereUserid($authInfo['userid'])->whereEmail($authInfo['email'])->whereEncrypt($authInfo['encrypt'])->exists()) { - return $authInfo['userid']; - } - } - return 0; - }); - if (empty($userid)) { - Cache::forget($cacheKey); + Doo::load($get['token'], $get['language']); + // + if (Doo::userId() > 0 + && !Doo::userExpired() + && $user = User::whereUserid(Doo::userId())->whereEmail(Doo::userEmail())->whereEncrypt(Doo::userEncrypt())->first()) { + // 保存用户 + $this->saveUser($fd, $user->userid); + // 发送open事件 + $server->push($fd, Base::array2json([ + 'type' => 'open', + 'data' => [ + 'fd' => $fd, + ], + ])); + // 通知上线 + Task::deliver(new LineTask($user->userid, true)); + // 推送离线时收到的消息 + Task::deliver(new PushTask("RETRY::" . $user->userid)); + } else { + // 用户不存在 $server->push($fd, Base::array2json([ 'type' => 'error', 'data' => [ - 'error' => '成员不存在' + 'error' => 'No member' ], ])); $server->close($fd); $this->deleteUser($fd); - return; } - // 保存用户、发送open事件 - $this->saveUser($fd, $userid); - $server->push($fd, Base::array2json([ - 'type' => 'open', - 'data' => [ - 'fd' => $fd, - ], - ])); - // 通知上线 - Task::deliver(new LineTask($userid, true)); - // 推送离线时收到的消息 - Task::deliver(new PushTask("RETRY::" . $userid)); } break; @@ -103,11 +93,6 @@ class WebSocketService implements WebSocketHandlerInterface */ public function onMessage(Server $server, Frame $frame) { - global $_A; - $_A = [ - '__static_langdata' => [], - ]; - // $msg = Base::json2array($frame->data); $type = $msg['type']; // 消息类型 $msgId = $msg['msgId']; // 消息ID(用于回调) diff --git a/app/Tasks/BotReceiveMsgTask.php b/app/Tasks/BotReceiveMsgTask.php index 2db6dbcad..a63e881d6 100644 --- a/app/Tasks/BotReceiveMsgTask.php +++ b/app/Tasks/BotReceiveMsgTask.php @@ -222,7 +222,7 @@ class BotReceiveMsgTask extends AbstractTask $botId = $isManager ? $array[1] : $botUser->userid; $data = $this->botManagerOne($botId, $msg->userid); if ($data) { - User::token($data); + User::generateToken($data); } else { $type = "notice"; $notice = "机器人不存在。"; @@ -345,7 +345,7 @@ class BotReceiveMsgTask extends AbstractTask if ($userBot && preg_match("/^https*:\/\//", $userBot->webhook_url)) { Ihttp::ihttp_post($userBot->webhook_url, [ 'text' => $command, - 'token' => User::token($botUser), + 'token' => User::generateToken($botUser), 'dialog_id' => $msg->dialog_id, 'msg_id' => $msg->id, 'msg_uid' => $msg->userid, diff --git a/cmd b/cmd index 311b50083..5ac073bac 100755 --- a/cmd +++ b/cmd @@ -345,6 +345,7 @@ if [ $# -gt 0 ]; then ;; esac $COMPOSE down + env_set APP_DEBUG "false" rm -rf "./docker/mysql/data" rm -rf "./docker/log/supervisor" find "./storage/logs" -name "*.log" | xargs rm -rf