diff --git a/app/api/controller/Account.php b/app/api/controller/Account.php index a4f3aa8..c3e39e6 100644 --- a/app/api/controller/Account.php +++ b/app/api/controller/Account.php @@ -19,7 +19,8 @@ use support\Response; class Account extends Frontend { protected array $noNeedLogin = ['retrievePassword']; - protected array $noNeedPermission = ['verification', 'changeBind']; + // 移动端 API 不走会员权限表(user_group/user_rule)校验,仅校验登录态 + protected array $noNeedPermission = ['*']; public function userProfile(Request $request): Response { @@ -44,7 +45,6 @@ class Account extends Frontend 'code' => 1, 'message' => __('ok'), 'data' => [ - 'id' => $user->id, 'username' => $user->username, 'head_image' => $user->avatar ?? '', 'coin' => $user->coin, @@ -172,7 +172,7 @@ class Account extends Frontend if (!Token::check($params['accountVerificationToken'], $params['type'] . '-pass', $user->id)) { return $this->error(__('You need to verify your account before modifying the binding information')); } - } elseif (!isset($params['password']) || !verify_password($params['password'], $user->password, ['salt' => $user->salt])) { + } elseif (!isset($params['password']) || !verify_password($params['password'], $user->password, ['salt' => $user->salt ?? ''])) { return $this->error(__('Password error')); } @@ -213,7 +213,7 @@ class Account extends Frontend $model = $this->auth->getUser(); $params = $request->only(['oldPassword', 'newPassword']); - if (!verify_password($params['oldPassword'], $model->password, ['salt' => $model->salt])) { + if (!verify_password($params['oldPassword'], $model->password, ['salt' => $model->salt ?? ''])) { return $this->error(__('Old password error')); } diff --git a/app/api/controller/Auth.php b/app/api/controller/Auth.php index 82aa976..99eb532 100644 --- a/app/api/controller/Auth.php +++ b/app/api/controller/Auth.php @@ -14,7 +14,8 @@ use support\Response; class Auth extends MobileBase { - protected array $noNeedLogin = ['userRegister', 'userLogin', 'tokenRefresh']; + protected array $noNeedLogin = ['register', 'login', 'refreshToken', 'userRegister', 'userLogin', 'tokenRefresh']; + protected array $noNeedAuthToken = ['register', 'login', 'refreshToken', 'userRegister', 'userLogin', 'tokenRefresh']; public function userRegister(Request $request): Response { @@ -23,27 +24,22 @@ class Auth extends MobileBase return $response; } - $account = trim((string) $request->post('account', '')); - $accountType = trim((string) $request->post('account_type', '')); + $username = trim((string) $request->post('username', '')); + if ($username === '') { + $username = trim((string) $request->post('account', '')); + } $password = (string) $request->post('password', ''); $inviteCode = trim((string) $request->post('invite_code', '')); - if ($account === '' || $accountType === '' || $password === '') { + if ($username === '' || $password === '') { return $this->mobileError(1001, 'Missing parameters'); } - if ($accountType !== 'phone' && $accountType !== 'email') { - return $this->mobileError(1003, 'Invalid parameter value'); + if (!preg_match('/^1[3-9]\d{9}$/', $username)) { + return $this->mobileError(1003, 'Please enter the correct mobile number'); } - $username = $account; - $mobile = ''; + $phone = $username; $email = ''; - if ($accountType === 'phone') { - $mobile = $account; - } - if ($accountType === 'email') { - $email = $account; - } $extend = []; if ($inviteCode !== '') { @@ -56,7 +52,7 @@ class Auth extends MobileBase $extend['channel_id'] = $inviterAdmin['channel_id'] ?? null; } - $registered = $this->auth->register($username, $password, $mobile, $email, 1, $extend); + $registered = $this->auth->register($username, $password, $phone, $email, 1, $extend); if (!$registered) { return $this->mobileError(2000, (string) $this->auth->getError()); } @@ -66,17 +62,7 @@ class Auth extends MobileBase return $this->mobileError(2000, 'Registered successfully but login failed'); } - $userInfo = $this->auth->getUserInfo(); - return $this->mobileSuccess([ - 'user_id' => $userInfo['id'] ?? null, - 'access_token' => $userInfo['token'] ?? '', - 'expires_in' => config('buildadmin.user_token_keep_time', 259200), - 'profile' => [ - 'username' => $userInfo['username'] ?? '', - 'coin' => $userInfo['coin'] ?? '0.0000', - 'channel_id' => $userInfo['channel_id'] ?? null, - ], - ]); + return $this->mobileSuccess($this->buildLoginPayload()); } public function userLogin(Request $request): Response @@ -86,28 +72,20 @@ class Auth extends MobileBase return $response; } - $account = trim((string) $request->post('account', '')); + $username = trim((string) $request->post('username', '')); + if ($username === '') { + $username = trim((string) $request->post('account', '')); + } $password = (string) $request->post('password', ''); - if ($account === '' || $password === '') { + if ($username === '' || $password === '') { return $this->mobileError(1001, 'Missing parameters'); } - $ok = $this->auth->login($account, $password, true); + $ok = $this->auth->login($username, $password, true); if (!$ok) { return $this->mobileError(1101, 'Incorrect account or password'); } - $userInfo = $this->auth->getUserInfo(); - return $this->mobileSuccess([ - 'access_token' => $userInfo['token'] ?? '', - 'refresh_token' => $userInfo['refresh_token'] ?? '', - 'expires_in' => config('buildadmin.user_token_keep_time', 259200), - 'user' => [ - 'id' => $userInfo['id'] ?? null, - 'username' => $userInfo['username'] ?? '', - 'coin' => $userInfo['coin'] ?? '0.0000', - 'risk_flags' => $userInfo['risk_flags'] ?? 0, - ], - ]); + return $this->mobileSuccess($this->buildLoginPayload()); } public function tokenRefresh(Request $request): Response @@ -130,9 +108,25 @@ class Auth extends MobileBase $newToken = Random::uuid(); Token::set($newToken, UserAuth::TOKEN_TYPE, $tokenData['user_id'], config('buildadmin.user_token_keep_time', 259200)); return $this->mobileSuccess([ - 'access_token' => $newToken, + 'user-token' => $newToken, 'expires_in' => config('buildadmin.user_token_keep_time', 259200), ]); } + + private function buildLoginPayload(): array + { + $userInfo = $this->auth->getUserInfo(); + return [ + 'user-token' => $userInfo['token'] ?? '', + 'refresh_token' => $userInfo['refresh_token'] ?? '', + 'expires_in' => config('buildadmin.user_token_keep_time', 259200), + 'user' => [ + 'username' => $userInfo['username'] ?? '', + 'coin' => $userInfo['coin'] ?? '0.0000', + 'channel_id' => $userInfo['channel_id'] ?? null, + 'risk_flags' => $userInfo['risk_flags'] ?? 0, + ], + ]; + } } diff --git a/app/api/controller/Ems.php b/app/api/controller/Ems.php index 53bbc68..0d831d7 100644 --- a/app/api/controller/Ems.php +++ b/app/api/controller/Ems.php @@ -74,7 +74,7 @@ class Ems extends Frontend return $this->error(__('Please use the account registration email to send the verification code')); } $password = $request->post('password'); - if (!verify_password($password, $this->auth->password, ['salt' => $this->auth->salt])) { + if (!verify_password($password, $this->auth->password, ['salt' => $this->auth->salt ?? ''])) { return $this->error(__('Password error')); } } diff --git a/app/api/lang/en.php b/app/api/lang/en.php index 1449bc8..ba9c42f 100644 --- a/app/api/lang/en.php +++ b/app/api/lang/en.php @@ -22,6 +22,8 @@ return [ 'Invalid signature' => 'Invalid signature', 'Invalid timestamp' => 'Invalid timestamp', 'Invite code does not exist' => 'Invite code does not exist', + 'Register only supports phone' => 'Register only supports phone', + 'Please enter the correct mobile number' => 'Please enter the correct mobile number', 'Registered successfully but login failed' => 'Registered successfully but login failed', 'Incorrect account or password' => 'Incorrect account or password', 'Login status has expired' => 'Login status has expired', diff --git a/app/api/lang/zh-cn.php b/app/api/lang/zh-cn.php index 29dffa7..115b432 100644 --- a/app/api/lang/zh-cn.php +++ b/app/api/lang/zh-cn.php @@ -54,6 +54,8 @@ return [ 'Invalid signature' => '签名错误', 'Invalid timestamp' => '时间戳无效', 'Invite code does not exist' => '邀请码不存在', + 'Register only supports phone' => '注册仅支持手机号', + 'Please enter the correct mobile number' => '请输入正确的手机号', 'Registered successfully but login failed' => '注册成功但登录失败', 'Incorrect account or password' => '账号或密码错误', 'Login status has expired' => '登录状态已过期', diff --git a/app/common/controller/Frontend.php b/app/common/controller/Frontend.php index e29ae8f..5f277e7 100644 --- a/app/common/controller/Frontend.php +++ b/app/common/controller/Frontend.php @@ -36,7 +36,13 @@ class Frontend extends Api try { $this->auth = Auth::instance(['request' => $request]); - $token = get_auth_token(['ba', 'user', 'token'], $request); + $token = trim((string) $request->header('user-token', '')); + if ($token === '') { + $token = trim((string) $request->header('user_token', '')); + } + if ($token === '') { + $token = get_auth_token(['ba', 'user', 'token'], $request); + } if ($token) $this->auth->init($token); } catch (TokenExpirationException) { if ($needLogin) return $this->error(__('Token expiration'), [], 409); diff --git a/app/common/library/Auth.php b/app/common/library/Auth.php index 3174717..3a20a67 100644 --- a/app/common/library/Auth.php +++ b/app/common/library/Auth.php @@ -67,7 +67,8 @@ class Auth extends \ba\Auth $this->setError('Account not exist'); return false; } - if ($this->model->status != 'enable') { + $status = $this->model->status ?? ''; + if ($status === 'disable' || $status === 0 || $status === '0') { $this->setError('Account disabled'); return false; } @@ -81,7 +82,7 @@ class Auth extends \ba\Auth return false; } - public function register(string $username, string $password = '', string $mobile = '', string $email = '', int $group = 1, array $extend = []): bool + public function register(string $username, string $password = '', string $phone = '', string $email = '', int $group = 1, array $extend = []): bool { $request = function_exists('request') ? request() : null; $ip = $request ? $request->getRealIp() : '0.0.0.0'; @@ -90,7 +91,9 @@ class Auth extends \ba\Auth $this->setError(__('Email')); return false; } - if ($username && !preg_match('/^[a-zA-Z][a-zA-Z0-9_]{2,15}$/', $username)) { + $isMobileUsername = preg_match('/^1[3-9]\d{9}$/', $username) === 1; + $isNormalUsername = preg_match('/^[a-zA-Z][a-zA-Z0-9_]{2,15}$/', $username) === 1; + if ($username && !$isMobileUsername && !$isNormalUsername) { $this->setError(__('Username')); return false; } @@ -112,9 +115,9 @@ class Auth extends \ba\Auth 'join_time' => $time, 'last_login_ip' => $ip, 'last_login_time' => $time, - 'status' => 'enable', + 'status' => 1, ]; - $data = array_merge(compact('username', 'password', 'mobile', 'email'), $data, $extend); + $data = array_merge(compact('username', 'password', 'phone', 'email'), $data, $extend); Db::startTrans(); try { @@ -139,7 +142,7 @@ class Auth extends \ba\Auth public function login(string $username, string $password, bool $keep): bool { $accountType = false; - if (preg_match('/^1[3-9]\d{9}$/', $username)) $accountType = 'mobile'; + if (preg_match('/^1[3-9]\d{9}$/', $username)) $accountType = 'phone'; elseif (filter_var($username, FILTER_VALIDATE_EMAIL)) $accountType = 'email'; elseif (preg_match('/^[a-zA-Z][a-zA-Z0-9_]{2,15}$/', $username)) $accountType = 'username'; if (!$accountType) { @@ -152,7 +155,8 @@ class Auth extends \ba\Auth $this->setError('Account not exist'); return false; } - if ($this->model->status == 'disable') { + $status = $this->model->status ?? ''; + if ($status === 'disable' || $status === 0 || $status === '0') { $this->setError('Account disabled'); return false; } @@ -171,7 +175,7 @@ class Auth extends \ba\Auth } } - if (!verify_password($password, $this->model->password, ['salt' => $this->model->salt])) { + if (!verify_password($password, $this->model->password, ['salt' => $this->model->salt ?? ''])) { $this->loginFailed(); $this->setError('Password is incorrect'); return false; diff --git a/app/common/middleware/AllowCrossDomain.php b/app/common/middleware/AllowCrossDomain.php index 842e724..deee08f 100644 --- a/app/common/middleware/AllowCrossDomain.php +++ b/app/common/middleware/AllowCrossDomain.php @@ -30,7 +30,7 @@ class AllowCrossDomain implements MiddlewareInterface 'Access-Control-Allow-Credentials' => 'true', 'Access-Control-Max-Age' => '1800', 'Access-Control-Allow-Methods' => 'GET, POST, PUT, DELETE, PATCH, OPTIONS', - 'Access-Control-Allow-Headers' => 'Content-Type, Authorization, batoken, ba-user-token, think-lang, server', + 'Access-Control-Allow-Headers' => 'Content-Type, Authorization, batoken, ba-user-token, user-token, access-token, think-lang, server', ]; $origin = $request->header('origin'); if (is_array($origin)) { diff --git a/app/common/model/User.php b/app/common/model/User.php index 8d1b706..909a91e 100644 --- a/app/common/model/User.php +++ b/app/common/model/User.php @@ -32,4 +32,9 @@ class User extends Model { return $this->belongsTo(\app\admin\model\Admin::class, 'admin_id', 'id'); } + + public function resetPassword(int|string $uid, string $newPassword): int + { + return $this->where(['id' => $uid])->update(['password' => hash_password($newPassword)]); + } } diff --git a/app/functions.php b/app/functions.php index 5537463..d99306b 100644 --- a/app/functions.php +++ b/app/functions.php @@ -161,6 +161,20 @@ if (!function_exists('get_auth_token')) { } } } + $authorization = $request->header('authorization'); + if (is_string($authorization) && preg_match('/^\s*Bearer\s+(.+?)\s*$/i', $authorization, $matches) === 1) { + $tokens[] = $matches[1]; + } + foreach (['user_token', 'user-token', 'access_token', 'access-token'] as $key) { + $headerToken = $request->header($key); + if ($headerToken) { + $tokens[] = $headerToken; + } + $paramToken = $request->get($key) ?? $request->post($key); + if ($paramToken) { + $tokens[] = $paramToken; + } + } return $tokens[0] ?? ''; } } diff --git a/config/route.php b/config/route.php index 06d8e39..118df95 100644 --- a/config/route.php +++ b/config/route.php @@ -111,11 +111,17 @@ Route::post('/api/account/retrievePassword', [\app\api\controller\Account::class // api/ems Route::post('/api/ems/send', [\app\api\controller\Ems::class, 'send']); -// ==================== 移动端游戏接口(36字花) ==================== +// ==================== 移动端用户接口(统一收口到 /api/user/*) ==================== +Route::post('/api/user/register', [\app\api\controller\Auth::class, 'userRegister']); +Route::post('/api/user/login', [\app\api\controller\Auth::class, 'userLogin']); +Route::post('/api/user/refreshToken', [\app\api\controller\Auth::class, 'tokenRefresh']); +Route::get('/api/user/profile', [\app\api\controller\Account::class, 'userProfile']); +Route::post('/api/user/retrievePassword', [\app\api\controller\Account::class, 'retrievePassword']); + +// 兼容旧移动端路径,后续客户端切换完成后可移除 Route::post('/api/auth/userRegister', [\app\api\controller\Auth::class, 'userRegister']); Route::post('/api/auth/userLogin', [\app\api\controller\Auth::class, 'userLogin']); Route::post('/api/auth/tokenRefresh', [\app\api\controller\Auth::class, 'tokenRefresh']); - Route::get('/api/account/userProfile', [\app\api\controller\Account::class, 'userProfile']); Route::get('/api/game/lobbyInit', [\app\api\controller\Game::class, 'lobbyInit']); diff --git a/web/src/api/frontend/user/index.ts b/web/src/api/frontend/user/index.ts index 069a982..1570dbd 100644 --- a/web/src/api/frontend/user/index.ts +++ b/web/src/api/frontend/user/index.ts @@ -109,7 +109,7 @@ export function postLogout() { export function retrievePassword(params: anyObj) { return createAxios( { - url: accountUrl + 'retrievePassword', + url: userUrl + 'retrievePassword', method: 'POST', data: params, },