当前位置: 首页 > news >正文

Fastadmin开发两个APP端,接口token验证

假设两个APP分别是用户端和内部端

结构如下

API (用户端接口)

/api/
├── auth/          # 认证相关
├── users/         # 用户相关
├── products/      # 商品相关
└── orders/        # 订单相关

Internal (内部端接口)

/internal/
├── auth/          # 认证相关
├── users/         # 用户相关
├── products/      # 商品相关
└── orders/        # 订单相关

 

找到文件 application/common/library/Auth.php

增加一个类型

    // 新增类型标识属性,api客户端,internal内部端protected $type = 'api';

在instance方法中增加处理参数的代码

        // 处理类型参数if (is_array($options) && isset($options['type'])) {self::$instance->setType($options['type']);}
    public function setType($type){$this->type = $type;// 加载对应类型的配置$config = Config::get("auth_groups.{$type}", []);// 合并配置到options$this->options = array_merge($this->options, $config);return $this;}

 Token初始化中处理前缀

    /*** 根据Token初始化** @param string $token Token* @return boolean*/public function init($token){if ($this->_logined) {return true;}if ($this->_error) {return false;}// 验证Token前缀if (!preg_match("/^{$this->type}_/", $token)) {$this->setError('Invalid token type');return false;}$data = Token::get($token);if (!$data) {return false;}$user_id = intval($data['user_id']);$modelClass = $this->options['model'] ?? User::class; // 动态模型if ($user_id > 0) {// $user = User::get($user_id);$user = $modelClass::get($user_id);if (!$user) {$this->setError('Account not exist');return false;}

 

修改register方法中的设置token

//设置Token
// $this->_token = Random::uuid();
$rawToken = Random::uuid();
$this->_token = "{$this->type}_{$rawToken}";

 

login方法中动态获取登录字段

    public function login($account, $password){// $field = Validate::is($account, 'email') ? 'email' : (Validate::regex($account, '/^1\d{10}$/') ? 'mobile' : 'username');// $user = User::get([$field => $account]);// 动态获取登录字段 -------------------------$field = $this->detectLoginField($account);$modelClass = $this->options['model'] ?? User::class;$user = $modelClass::get([$field => $account]);// -----------------------------------------if (!$user) {$this->setError('Account is incorrect');return false;}
    // 新增登录字段检测方法 ---------------------------protected function detectLoginField($account){// 从配置获取字段检测规则$loginField = $this->options['login_field'] ?? ['username', 'email', 'mobile'];if (is_string($loginField)) {return $loginField; // 直接指定字段
        }// 默认检测逻辑foreach ($loginField as $field) {if ($field === 'email' && Validate::is($account, 'email')) {return 'email';}if ($field === 'mobile' && Validate::regex($account, '/^1\d{10}$/')) {return 'mobile';}}return 'username';}

 

直接登录账号direct方法

    public function direct($user_id){// $user = User::get($user_id);$modelClass = $this->options['model'] ?? User::class;$user = $modelClass::get($user_id);
    // .....原代码

    // $this->_token = Random::uuid();
    $rawToken = Random::uuid();
    $this->_token = "{$this->type}_{$rawToken}";
    Token::set($this->_token, $user->id, $this->keeptime);

 

获取会员基本信息中增加账号类型

    /*** 获取会员基本信息*/public function getUserinfo(){$data = $this->_user->toArray();$allowFields = $this->getAllowFields();$userinfo = array_intersect_key($data, array_flip($allowFields));$userinfo = array_merge($userinfo, Token::get($this->_token));$userinfo['avatar'] = url($userinfo['avatar'], '', false, true);// 账号类型$userinfo['account_type'] = $this->type;return $userinfo;}

 

给内部端设置用户表

CREATE TABLE `fa_internal_user` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',`group_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '组别ID',`username` varchar(32) DEFAULT '' COMMENT '用户名',`nickname` varchar(50) DEFAULT '' COMMENT '昵称',`password` varchar(32) DEFAULT '' COMMENT '密码',`salt` varchar(30) DEFAULT '' COMMENT '密码盐',`email` varchar(100) DEFAULT '' COMMENT '电子邮箱',`mobile` varchar(11) DEFAULT '' COMMENT '手机号',`avatar` varchar(255) DEFAULT '' COMMENT '头像',`level` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '等级',`gender` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '性别',`birthday` date DEFAULT NULL COMMENT '生日',`bio` varchar(100) DEFAULT '' COMMENT '格言',`money` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '余额',`score` int(10) NOT NULL DEFAULT '0' COMMENT '积分',`successions` int(10) unsigned NOT NULL DEFAULT '1' COMMENT '连续登录天数',`maxsuccessions` int(10) unsigned NOT NULL DEFAULT '1' COMMENT '最大连续登录天数',`prevtime` bigint(16) DEFAULT NULL COMMENT '上次登录时间',`logintime` bigint(16) DEFAULT NULL COMMENT '登录时间',`loginip` varchar(50) DEFAULT '' COMMENT '登录IP',`loginfailure` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '失败次数',`loginfailuretime` bigint(16) DEFAULT NULL COMMENT '最后登录失败时间',`joinip` varchar(50) DEFAULT '' COMMENT '加入IP',`jointime` bigint(16) DEFAULT NULL COMMENT '加入时间',`createtime` bigint(16) DEFAULT NULL COMMENT '创建时间',`updatetime` bigint(16) DEFAULT NULL COMMENT '更新时间',`token` varchar(50) DEFAULT '' COMMENT 'Token',`status` varchar(30) DEFAULT '' COMMENT '状态',`verification` varchar(255) DEFAULT '' COMMENT '验证',PRIMARY KEY (`id`),KEY `username` (`username`),KEY `email` (`email`),KEY `mobile` (`mobile`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='内部端会员表';

 

增加Model 文件  application/common/model/InternalUser.php

 

增加内部端API基类 application/common/controller/InternalApi.php ,在internal模块下面controller都继承这个基类

<?phpnamespace app\common\controller;use app\common\library\Auth;
use think\Config;
use think\Hook;
use think\Loader;
use think\Validate;/*** 内部端API基类*/
class InternalApi extends Api
{/*** 初始化操作 (重写父类方法)*/protected function _initialize(){// 跨域请求检测
        check_cors_request();// 检测IP是否允许
        check_ip_allowed();// 移除HTML标签$this->request->filter('trim,strip_tags,htmlspecialchars');// 初始化批发商端权限实例$this->auth = Auth::instance(['type' => 'internal']);$modulename = $this->request->module();$controllername = Loader::parseName($this->request->controller());$actionname = strtolower($this->request->action());// 获取Token$token = $this->request->server('HTTP_INTERNALTOKEN', $this->request->request('internaltoken', \think\Cookie::get('internaltoken')));$path = str_replace('.', '/', $controllername) . '/' . $actionname;// 设置当前请求的URI$this->auth->setRequestUri($path);// 检测是否需要验证登录if (!$this->auth->match($this->noNeedLogin)) {// 初始化内部端Token$this->auth->init($token);// 检测是否登录if (!$this->auth->isLogin()) {$this->error("请先登录", null, 401);}// 判断是否需要验证权限if (!$this->auth->match($this->noNeedRight)) {// 使用内部端权限规则校验// if (!$this->auth->check($path)) {//     $this->error(__('You have no permission'), null, 403);// }
            }} else {// 如果有传递token才验证是否登录状态if ($token) {$this->auth->init($token);}}// 公共上传配置(保持与用户端一致)$upload = \app\common\model\Config::upload();Hook::listen("upload_config_init", $upload);Config::set('upload', array_merge(Config::get('upload'), $upload));// 加载当前控制器语言包$this->loadlang($controllername);}/*** 刷新Token(重写父类方法)*/protected function token(){$token = $this->request->param('__token__');// 使用内部端专用Token验证规则if (!Validate::make()->check(['__token__' => $token], ['__token__' => 'require|token:store'])) {$this->error(__('Token verification error'), ['__token__' => $this->request->token('internal')]);}// 刷新内部端专用Token$this->request->token('internal', 'md5');}
}

 

最后在application/config.php 里面增加一个配置

    'auth_groups' => ['api'  => ['model'       => \app\common\model\User::class,'login_field' => 'mobile',//['username', 'email', 'mobile'],'keeptime'    => 2592000,],'internal' => ['model'       => \app\common\model\InternalUser::class,'login_field' => 'username','keeptime'    => 2592000,]],

 

这样,在请求api和internal的接口时,就可以验证各自的token

 

http://www.hskmm.com/?act=detail&tid=21582

相关文章:

  • 网易伏羲受邀亮相2025云栖大会,展示AI领域前沿创新成果
  • 2025 年人工智能培训机构最新推荐榜单:前五合规运营与产业适配能力深度解析及选择指南大模型培训/智能体培训/Agent培训机构推荐
  • 9年了 - ukyo-
  • js 获取下一个月时间和下一年的时间
  • 【Rust GUI开发入门】编写一个本地音乐播放器(5. 制作音乐列表组件) - Jordan
  • 【Nordic】nRF9151的SLM例程常用AT指令说明
  • sql server经典语句「转」
  • Codeforces 2149G Buratsuta 3 题解 [ 蓝 ] [ 摩尔投票 ] [ 线段树 ] [ 随机化 ] [ 主席树 ] [ 根号分治 ]
  • 2025 年最新推荐软件开发机构榜:聚焦微服务架构与 724 小时服务的优质厂商精选指南人力资源管理系统/资产管理系统/数据中台管理系统/流程管理系统软件开发公司推荐
  • 【半导体物理 | 学习笔记】第一章 半导体中的电子状态
  • 计数(5):多项式相关
  • 最新WTAPI开发微信机器人教程说明
  • 线性DP - 学习笔记
  • 2025 年最新制氮机厂家权威推荐排行榜:聚焦行业优质厂商综合实力,助力企业精准选购优质设备制氮机产生氮气/氮气纯化/设备改造/维修/保养/半导体用制氮机厂家推荐
  • 2025 年氨分解设备厂家最新推荐榜单:含半导体 / 冶金 / 稀土行业专用设备及品牌综合实力排名
  • 2025 阳台装修公司推荐榜:最新优质厂商资质 / 技术 / 服务测评,杭州浙江地区优选指南杭州阳台装修/浙江阳台装修公司推荐
  • bitset
  • 网易雷火胡志鹏:AI驱动未来,游戏科技重塑虚拟创造力与现实生产力
  • idea打包推送maven仓库及同时推送到不同的maven仓库,本地和云上的腾讯云
  • 2025 阳台柜厂家最新推荐榜:企业资质 / 材质 / 服务全景解析,选对品牌少走弯路杭州阳台柜/浙江阳台柜厂家推荐
  • 2025 年除湿机厂家最新权威推荐排行榜:实力厂家技术口碑评测及场景适配选购指南吊顶/泳池/车库/防爆/调温/新风除湿机厂家推荐
  • 2025 年液氨蒸发器厂家联系方式,众众电热:多领域加热设备供应与定制化解决方案提供商
  • 【Batch】批量修改文件后缀
  • 【solace】基于docker部署solace环境
  • 2025 年阿里巴巴开通实力商家店铺开通代运营 / 阿里巴巴新手开店全托管代运营公司推荐:南鑫粤网络 —— 全域运营解决方案与实战服务优势解析
  • Vue-element-admin开发指南 - 教程
  • 2025 年国内工作服厂家最新推荐排行榜:聚焦工艺设计与服务,精选权威榜单助企业采购冬季/春季/工人/车间/防静电/餐饮/劳保工作服厂家推荐
  • ClickHouse 窗口函数使用详解(一) - 若
  • ClickHouse 窗口函数详解:告别 GROUP BY 的局限性,实现灵活数据分析 - 若
  • 简单WEB网站