chore: 入库生产基线(2026-10-26 与 shop.douba.top 一致)
- 11 个已跟踪文件的在途改动此前只存在于工作区,生产已在运行 - 补入两个从未入库的文件:InternalController.php(app_03/box_app 内部接口)、 config/internal.php(内部通信 key,值从 .env 读取,不含硬编码密钥) - 逐文件 md5 比对过生产,内容一致 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
134
app/controller/api/v1/InternalController.php
Normal file
134
app/controller/api/v1/InternalController.php
Normal file
@@ -0,0 +1,134 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\controller\api\v1;
|
||||
|
||||
use app\Request;
|
||||
use app\services\user\UserServices;
|
||||
use app\services\wechat\RoutineServices;
|
||||
use app\services\wechat\WechatUserServices;
|
||||
use think\db\exception\DataNotFoundException;
|
||||
use think\db\exception\DbException;
|
||||
use think\db\exception\ModelNotFoundException;
|
||||
use think\exception\ValidateException;
|
||||
use think\Response;
|
||||
|
||||
/**
|
||||
* 内部服务接口(不经过用户认证)
|
||||
* 用于 H5 / app_03 后端通过 openid 自动补齐用户信息
|
||||
*/
|
||||
class InternalController
|
||||
{
|
||||
/**
|
||||
* 验证内部 API Key
|
||||
* @param Request $request
|
||||
* @return bool true=通过,false=拒绝
|
||||
*/
|
||||
private function checkInternalKey(Request $request): bool
|
||||
{
|
||||
$apiKey = $request->header('X-Internal-Key');
|
||||
// 注意:在 Swoole 沙箱里 env()/getenv() 经常读不到 .env
|
||||
// 用 config() 兜底,确保两种部署(PHP-FPM / Swoole)都生效
|
||||
$configKey = (string)(config('internal.api_key') ?: env('INTERNAL_API_KEY', ''));
|
||||
return $apiKey && $configKey && $apiKey === $configKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 openid 获取用户信息
|
||||
* @param Request $request
|
||||
* @param WechatUserServices $wechatUserServices
|
||||
* @return Response
|
||||
*/
|
||||
public function userInfo(Request $request, WechatUserServices $wechatUserServices): Response
|
||||
{
|
||||
if (!$this->checkInternalKey($request)) {
|
||||
return Response::create(['code' => 403, 'msg' => 'Forbidden'], 'json');
|
||||
}
|
||||
|
||||
$openid = $request->param('openid', '');
|
||||
if (!$openid) {
|
||||
return Response::create(['code' => 400, 'msg' => 'openid is required'], 'json');
|
||||
}
|
||||
|
||||
try {
|
||||
$wechatUser = $wechatUserServices->getWechatUserInfo(['openid' => $openid]);
|
||||
} catch (DataNotFoundException | ModelNotFoundException | DbException $e) {
|
||||
return Response::create(['code' => 500, 'msg' => '查询失败'], 'json');
|
||||
}
|
||||
if (!$wechatUser) {
|
||||
return Response::create(['code' => 404, 'msg' => 'user not found'], 'json');
|
||||
}
|
||||
|
||||
$uid = (int)$wechatUser['uid'];
|
||||
$userServices = app()->make(UserServices::class);
|
||||
try {
|
||||
$user = $userServices->getUserInfo($uid);
|
||||
} catch (DataNotFoundException | ModelNotFoundException | DbException $e) {
|
||||
$user = null;
|
||||
}
|
||||
|
||||
return Response::create([
|
||||
'code' => 200,
|
||||
'data' => [
|
||||
'uid' => $uid,
|
||||
'nickname' => $user['nickname'] ?? $wechatUser['nickname'] ?? '',
|
||||
'phone' => $user['phone'] ?? $wechatUser['phone'] ?? '',
|
||||
'avatar' => $user['avatar'] ?? $wechatUser['headimgurl'] ?? '',
|
||||
],
|
||||
], 'json');
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过微信 code 换 openid(绕过 store_user_mobile 限制)
|
||||
*
|
||||
* 设计目的:H5/app_03 在新用户场景下(CRMEB 强制绑手机号=true),
|
||||
* 原 silenceAuth 返回 {auth_login:1, key:...},前端拿不到 openid 会被
|
||||
* 引导到授权页。本端点只调微信 code2session 拿 openid/unionid,不查
|
||||
* store_user_mobile、不建用户、不发 token,前端拿到 openid 后走自己的
|
||||
* openid-login 即可自助登录。
|
||||
*
|
||||
* @param Request $request
|
||||
* @param RoutineServices $routineServices
|
||||
* @return Response
|
||||
*/
|
||||
public function getOpenidByCode(Request $request, RoutineServices $routineServices): Response
|
||||
{
|
||||
if (!$this->checkInternalKey($request)) {
|
||||
return Response::create(['code' => 403, 'msg' => 'Forbidden'], 'json');
|
||||
}
|
||||
|
||||
$code = $request->param('code', '');
|
||||
if (!$code) {
|
||||
return Response::create(['code' => 400, 'msg' => 'code is required'], 'json');
|
||||
}
|
||||
|
||||
try {
|
||||
$wechatInfo = $routineServices->getUserInfoByCode((string)$code);
|
||||
} catch (ValidateException $e) {
|
||||
return Response::create(['code' => 400, 'msg' => $e->getMessage()], 'json');
|
||||
} catch (\Throwable $e) {
|
||||
return Response::create(['code' => 500, 'msg' => 'code2session 失败: ' . $e->getMessage()], 'json');
|
||||
}
|
||||
|
||||
$openid = $wechatInfo['openid'] ?? '';
|
||||
if (!$openid) {
|
||||
return Response::create(['code' => 500, 'msg' => 'openid 缺失'], 'json');
|
||||
}
|
||||
|
||||
return Response::create([
|
||||
'code' => 200,
|
||||
'data' => [
|
||||
'openid' => $openid,
|
||||
'unionid' => $wechatInfo['unionid'] ?? '',
|
||||
],
|
||||
], 'json');
|
||||
}
|
||||
}
|
||||
@@ -151,7 +151,13 @@ class Routine
|
||||
{
|
||||
$token = $this->services->silenceAuth($code, (int)$spread_code, (int)$spread_spid, true);
|
||||
if ($token && isset($token['auth_login'])) {
|
||||
return app('json')->success('授权成功');
|
||||
// 透传 openid/unionid 给小程序端,用于向 H5 注入身份参数
|
||||
return app('json')->success('授权成功', [
|
||||
'auth_login' => $token['auth_login'],
|
||||
'key' => $token['key'],
|
||||
'openid' => $token['openid'] ?? '',
|
||||
'unionid' => $token['unionid'] ?? '',
|
||||
]);
|
||||
} else if ($token) {
|
||||
return app('json')->success('登录成功', ['token' => $token['token'], 'userInfo' => $token['userInfo'], 'expires_time' => $token['params']['exp'], 'store_user_avatar' => $token['store_user_avatar'] ?? 0]);
|
||||
} else
|
||||
|
||||
Reference in New Issue
Block a user