| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- <?php
- namespace App\Services\Account;
- use App\Consts\ErrorConst;
- use App\Facade\Site;
- use App\Libs\AliSMS;
- use App\Libs\Utils;
- use Illuminate\Support\Facades\DB;
- use OSS\Core\OssException;
- use OSS\OssClient;
- class AccountService
- {
- private $salt = 'bXBfYXVkaW8=';
- public function __construct() {}
- /**
- * @param $account
- * @param $passwd
- * @return array
- */
- public function login($account, $passwd): array
- {
- // 密码
- $pwd = md5($passwd . $this->salt);
- $user = DB::table('mp_manage_users')->where('account', $account)->where('pwd', $pwd)->where('is_deleted', 0)->first();
- if (!$user) {
- Utils::throwError('20003:用户不存在');
- }
- if ((int)getProp($user, 'is_enabled') === 0) {
- Utils::throwError('20003:用户已被禁用');
- }
- // 更新 token、token 过期时间与 refresh_token
- $uid = getProp($user, 'id');
- $nickname = getProp($user, 'nickname');
- $token = (string)getProp($user, 'token');
- $refreshToken = (string)getProp($user, 'refresh_token');
- if (!config('token.expire_check_enabled')) {
- // 开关关闭:仅依据 token 是否存在处理,不写入 token 过期时间与 refresh_token 相关字段
- if ($token === '') {
- $token = md5(makeRandStr(32));
- DB::table('mp_manage_users')->where('id', $uid)->update([
- 'token' => $token,
- 'updated_at' => date('Y-m-d H:i:s'),
- ]);
- }
- $tokenData = $this->currentTokenData($user);
- $tokenData['token'] = $token;
- } elseif ($token !== '' && $refreshToken !== ''
- && !$this->isExpired(getProp($user, 'token_expires_at'))
- && !$this->isExpired(getProp($user, 'refresh_token_expires_at'))) {
- // 已有可用登录态:重新登录不刷新 token 信息(多人协作共用一个账号时避免互相踢下线)
- $tokenData = $this->currentTokenData($user);
- } else {
- // 首次登录、老用户只有 token 没有 refresh_token、登录态已过期:补齐 token 过期时间与 refresh_token 相关字段
- // token 未过期时沿用原 token,避免多人协作场景下其余人掉线
- $keepToken = $token !== '' && !$this->isExpired(getProp($user, 'token_expires_at')) ? $token : '';
- $tokenData = $this->buildTokenData($keepToken);
- DB::table('mp_manage_users')->where('id', $uid)->update([
- 'token' => $tokenData['token'],
- 'token_expires_at' => $tokenData['token_expires_at'],
- 'refresh_token' => $tokenData['refresh_token'],
- 'refresh_token_expires_at' => $tokenData['refresh_token_expires_at'],
- 'updated_at' => date('Y-m-d H:i:s'),
- ]);
- }
- // 用户角色
- $role = getProp($user, 'role');
- return array_merge(compact('uid', 'nickname', 'role'), $tokenData);
- }
- public function userInfo(): array
- {
- $uid = Site::getUid();
- $user = DB::table('mp_manage_users')->where('id', $uid)->where('is_deleted', 0)->first();
- if (!$user) {
- Utils::throwError('20003:用户不存在');
- }
- if ((int)getProp($user, 'is_enabled') === 0) {
- Utils::throwError('20003:用户已被禁用');
- }
- // 更新token
- $uid = getProp($user, 'id');
- $nickname = getProp($user, 'nickname');
- $token = getProp($user, 'token');
- $token_expires_at = getProp($user, 'token_expires_at');
- if ($token_expires_at) $token_expires_at = transDate($token_expires_at);
- $refresh_token = getProp($user, 'refresh_token');
- $refresh_token_expires_at = getProp($user, 'refresh_token_expires_at');
- if ($refresh_token_expires_at) $refresh_token_expires_at = transDate($refresh_token_expires_at);
- // 用户角色
- $role = getProp($user, 'role');
- $points = getProp($user, 'points');
- $avatar = getProp($user, 'avatar');
- return compact('uid', 'nickname', 'avatar', 'token', 'token_expires_at', 'refresh_token', 'refresh_token_expires_at', 'role', 'points');
- }
- /**
- * 通过 refresh_token 刷新 token 与 refresh_token
- *
- * @param string $refreshToken
- * @return array
- */
- public function refreshToken($refreshToken): array
- {
- $refreshToken = trim((string)$refreshToken);
- if ($refreshToken === '') {
- Utils::throwError('1003:请传入refresh_token');
- }
- $user = DB::table('mp_manage_users')->where('refresh_token', $refreshToken)->where('is_deleted', 0)->first();
- if (!$user) {
- Utils::throwError(ErrorConst::TOKEN_EXPIRED);
- }
- if ((int)getProp($user, 'is_enabled') === 0) {
- Utils::throwError('20003:用户已被禁用');
- }
- // refresh_token 自身过期则不可续期,需重新登录
- $refreshTokenExpiresAt = getProp($user, 'refresh_token_expires_at');
- if ($refreshTokenExpiresAt && strtotime($refreshTokenExpiresAt) <= time()) {
- Utils::throwError(ErrorConst::TOKEN_EXPIRED);
- }
- $uid = (int)getProp($user, 'id');
- $nickname = getProp($user, 'nickname');
- $role = getProp($user, 'role');
- // 刷新时强制更换 token 与 refresh_token
- $tokenData = $this->buildTokenData();
- DB::table('mp_manage_users')->where('id', $uid)->update([
- 'token' => $tokenData['token'],
- 'token_expires_at' => $tokenData['token_expires_at'],
- 'refresh_token' => $tokenData['refresh_token'],
- 'refresh_token_expires_at' => $tokenData['refresh_token_expires_at'],
- 'updated_at' => date('Y-m-d H:i:s'),
- ]);
- return array_merge(compact('uid', 'nickname', 'role'), $tokenData);
- }
- /**
- * 生成 token、refresh_token 及其过期时间
- *
- * @param string $token 需要沿用的 token(传空则重新生成)
- * @return array
- */
- private function buildTokenData(string $token = ''): array
- {
- if ($token === '') {
- $token = md5(makeRandStr(32));
- }
- return [
- 'token' => $token,
- 'token_expires_at' => date('Y-m-d H:i:s', time() + (int)config('token.expire_seconds', 864000)),
- 'refresh_token' => md5(makeRandStr(32)),
- 'refresh_token_expires_at' => date('Y-m-d H:i:s', time() + (int)config('token.refresh_expire_seconds', 2592000)),
- ];
- }
- /**
- * 读取当前登录态(不做任何刷新)
- *
- * @param object $user 用户记录
- * @return array
- */
- private function currentTokenData($user): array
- {
- return [
- 'token' => (string)getProp($user, 'token'),
- 'token_expires_at' => transDate(getProp($user, 'token_expires_at')),
- 'refresh_token' => (string)getProp($user, 'refresh_token'),
- 'refresh_token_expires_at' => transDate(getProp($user, 'refresh_token_expires_at')),
- ];
- }
- /**
- * 时间是否已过期(空值视为未过期,兼容历史数据)
- *
- * @param mixed $expiresAt
- * @return bool
- */
- private function isExpired($expiresAt): bool
- {
- return (bool)($expiresAt && strtotime($expiresAt) <= time());
- }
- /**
- * 退出登录
- *
- * @param $token
- * @return bool
- */
- public function logout($token): bool
- {
- if (empty($token)) {
- return true;
- }
- // 退出不影响多设备
- return DB::table('mp_manage_users')->where('token', $token)->update([
- 'updated_at' => date('Y-m-d H:i:s')
- ]);
- }
- }
|