93 lines
3.1 KiB
PHP
93 lines
3.1 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
namespace app\api\controller\v1;
|
||
|
||
use ba\Random;
|
||
use Throwable;
|
||
use app\common\controller\Api;
|
||
use app\common\facade\Token;
|
||
use app\common\library\Auth as UserAuth;
|
||
use app\common\model\MallUserAsset;
|
||
use Webman\Http\Request;
|
||
use support\Response;
|
||
|
||
/**
|
||
* API v1 鉴权接口
|
||
*/
|
||
class Auth extends Api
|
||
{
|
||
|
||
/**
|
||
* 临时登录 token 有效期(秒)
|
||
*/
|
||
protected int $tempTokenExpire = 86400;
|
||
|
||
/**
|
||
* H5 临时登录(GET/POST)
|
||
* 参数:username
|
||
* 写入或复用 mall_user_asset;签发 muser 类型 token(user_id 为资产表主键)
|
||
*/
|
||
public function temLogin(Request $request): Response
|
||
{
|
||
$response = $this->initializeApi($request);
|
||
if ($response !== null) {
|
||
return $response;
|
||
}
|
||
|
||
$enabled = config('buildadmin.temp_login.enable', false);
|
||
if (!$enabled) {
|
||
return $this->error(__('Temp login is disabled'));
|
||
}
|
||
|
||
$username = trim(strval($request->get('username', $request->post('username', ''))));
|
||
// 兼容:querystring 中未编码的 '+' 会被解析为空格(application/x-www-form-urlencoded 规则)
|
||
// 例如:/api/v1/temLogin?username=+607... 期望保留 '+',则从原始 querystring 提取并还原
|
||
if ($username !== '' && str_contains($username, ' ')) {
|
||
$qs = $request->queryString();
|
||
if (is_string($qs) && $qs !== '') {
|
||
foreach (explode('&', $qs) as $pair) {
|
||
if ($pair === '' || !str_contains($pair, '=')) {
|
||
continue;
|
||
}
|
||
[$k, $v] = explode('=', $pair, 2);
|
||
if (rawurldecode($k) === 'username') {
|
||
// 先把 %xx 解码;注意这里不把 '+' 当空格处理,从而保留 '+'
|
||
$username = trim(rawurldecode($v));
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
if ($username === '') {
|
||
return $this->error(__('Parameter username can not be empty'));
|
||
}
|
||
|
||
try {
|
||
$asset = MallUserAsset::ensureForUsername($username);
|
||
} catch (Throwable $e) {
|
||
return $this->error($e->getMessage());
|
||
}
|
||
|
||
$token = Random::uuid();
|
||
$refreshToken = Random::uuid();
|
||
$expire = config('buildadmin.temp_login.expire', $this->tempTokenExpire);
|
||
$assetId = intval($asset->getKey());
|
||
Token::set($token, UserAuth::TOKEN_TYPE_MALL_USER, $assetId, $expire);
|
||
Token::set($refreshToken, UserAuth::TOKEN_TYPE_MALL_USER . '-refresh', $assetId, 2592000);
|
||
|
||
return $this->success('', [
|
||
'userInfo' => [
|
||
'id' => $assetId,
|
||
'username' => strval($asset->username ?? ''),
|
||
'nickname' => strval($asset->username ?? ''),
|
||
'playx_user_id' => strval($asset->playx_user_id ?? ''),
|
||
'token' => $token,
|
||
'refresh_token' => $refreshToken,
|
||
'expires_in' => $expire,
|
||
],
|
||
]);
|
||
}
|
||
}
|