227 行
7.0 KiB
PHP
227 行
7.0 KiB
PHP
<?php
|
||
namespace RiderApi\Controller;
|
||
use Think\Controller;
|
||
|
||
/**
|
||
* 骑手端基础控制器
|
||
* 提供token验证和用户身份认证功能
|
||
*/
|
||
class BaseController extends Controller {
|
||
|
||
protected $riderId = 0;
|
||
protected $riderInfo = null;
|
||
|
||
/**
|
||
* 初始化方法
|
||
*/
|
||
public function _initialize() {
|
||
// 设置返回格式为JSON
|
||
header('Content-Type: application/json; charset=utf-8');
|
||
// 允许跨域
|
||
header('Access-Control-Allow-Origin: *');
|
||
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
|
||
header('Access-Control-Allow-Headers: Content-Type, Authorization, Token');
|
||
|
||
// 处理OPTIONS请求
|
||
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
|
||
exit();
|
||
}
|
||
|
||
// 验证token(除了登录和发送验证码接口)
|
||
$action = ACTION_NAME;
|
||
$controller = CONTROLLER_NAME;
|
||
|
||
// 不需要验证token的接口
|
||
$noAuthActions = array(
|
||
'Auth' => array('login', 'sendCode'),
|
||
);
|
||
|
||
if (!isset($noAuthActions[$controller]) || !in_array($action, $noAuthActions[$controller])) {
|
||
$this->checkAuth();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 验证token和获取骑手信息
|
||
*/
|
||
protected function checkAuth() {
|
||
$token = $this->getToken();
|
||
|
||
if (empty($token)) {
|
||
$this->ajaxReturn(array('code' => 401, 'msg' => '请先登录'));
|
||
}
|
||
|
||
// 验证token并获取骑手信息
|
||
$riderInfo = $this->verifyToken($token);
|
||
|
||
if (!$riderInfo) {
|
||
$this->ajaxReturn(array('code' => 401, 'msg' => 'token无效,请重新登录'));
|
||
}
|
||
|
||
$this->riderId = $riderInfo['id'];
|
||
$this->riderInfo = $riderInfo;
|
||
}
|
||
|
||
/**
|
||
* 获取所有HTTP头信息(兼容不同PHP环境)
|
||
*/
|
||
protected function getAllHeaders() {
|
||
$headers = array();
|
||
|
||
// 如果getallheaders函数存在,直接使用
|
||
if (function_exists('getallheaders')) {
|
||
$headers = getallheaders();
|
||
} else {
|
||
// 手动从$_SERVER中提取HTTP头
|
||
foreach ($_SERVER as $key => $value) {
|
||
if (strpos($key, 'HTTP_') === 0) {
|
||
$header = str_replace('_', '-', substr($key, 5));
|
||
$header = ucwords(strtolower($header), '-');
|
||
$headers[$header] = $value;
|
||
}
|
||
}
|
||
}
|
||
|
||
return $headers;
|
||
}
|
||
|
||
/**
|
||
* 获取token
|
||
*/
|
||
protected function getToken() {
|
||
$token = '';
|
||
|
||
// 从Header中获取token
|
||
$headers = $this->getAllHeaders();
|
||
|
||
// 大小写不敏感的头部查找
|
||
$authHeader = '';
|
||
foreach ($headers as $key => $value) {
|
||
if (strtolower($key) === 'token') {
|
||
$token = $value;
|
||
break;
|
||
} elseif (strtolower($key) === 'authorization') {
|
||
$authHeader = $value;
|
||
}
|
||
}
|
||
|
||
// 如果没有找到Token头,处理Authorization头
|
||
if (empty($token) && !empty($authHeader)) {
|
||
// 支持Bearer token格式
|
||
if (strpos($authHeader, 'Bearer ') === 0) {
|
||
$token = substr($authHeader, 7);
|
||
} elseif (strpos($authHeader, 'bearer ') === 0) {
|
||
$token = substr($authHeader, 7);
|
||
}
|
||
}
|
||
|
||
// 如果Header中没有,尝试从POST参数中获取
|
||
if (empty($token)) {
|
||
$token = $this->getRequestParam('token', '');
|
||
}
|
||
|
||
// 如果POST中没有,尝试从GET参数中获取
|
||
if (empty($token)) {
|
||
$token = $this->getRequestParam('token', '');
|
||
}
|
||
|
||
return $token;
|
||
}
|
||
|
||
/**
|
||
* 验证token并返回骑手信息
|
||
*/
|
||
protected function verifyToken($token) {
|
||
if (empty($token)) {
|
||
return false;
|
||
}
|
||
|
||
// 从token表中查询有效的token
|
||
$tokenModel = M('rider_token');
|
||
$tokenInfo = $tokenModel->where(array(
|
||
'token' => $token,
|
||
'expires_at' => array('gt', date('Y-m-d H:i:s'))
|
||
))->find();
|
||
|
||
if (!$tokenInfo) {
|
||
return false;
|
||
}
|
||
|
||
// 获取骑手信息
|
||
$riderModel = M('rider_info');
|
||
$rider = $riderModel->where(array(
|
||
'id' => $tokenInfo['rider_id'],
|
||
'status' => 1
|
||
))->find();
|
||
|
||
if (!$rider) {
|
||
// 如果骑手不存在或已禁用,删除对应的token
|
||
$tokenModel->where(array('id' => $tokenInfo['id']))->delete();
|
||
return false;
|
||
}
|
||
|
||
// 更新token的最后使用时间(MySQL会自动更新updated_at字段)
|
||
$tokenModel->where(array('id' => $tokenInfo['id']))->save(array());
|
||
|
||
return $rider;
|
||
}
|
||
|
||
/**
|
||
* 统一的参数处理方法
|
||
* 自动识别JSON和表单格式的请求参数
|
||
* @param string $key 参数名
|
||
* @param mixed $default 默认值
|
||
* @return mixed 参数值
|
||
*/
|
||
protected function getRequestParam($key = null, $default = null) {
|
||
static $requestData = null;
|
||
|
||
// 只解析一次请求数据
|
||
if ($requestData === null) {
|
||
$requestData = array();
|
||
|
||
// 获取请求方法和Content-Type头
|
||
$requestMethod = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : 'GET';
|
||
$contentType = isset($_SERVER['CONTENT_TYPE']) ? $_SERVER['CONTENT_TYPE'] : '';
|
||
|
||
// 先合并GET和POST参数作为基础数据
|
||
$requestData = array_merge($_GET, $_POST);
|
||
|
||
// 如果是POST/PUT/PATCH请求且Content-Type是JSON格式
|
||
if (in_array($requestMethod, array('POST', 'PUT', 'PATCH')) &&
|
||
strpos($contentType, 'application/json') !== false) {
|
||
$input = file_get_contents('php://input');
|
||
if (!empty($input)) {
|
||
$jsonData = json_decode($input, true);
|
||
if (is_array($jsonData)) {
|
||
// JSON数据优先级更高,覆盖表单数据
|
||
$requestData = array_merge($requestData, $jsonData);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 如果没有指定key,返回所有参数
|
||
if ($key === null) {
|
||
return $requestData;
|
||
}
|
||
|
||
// 返回指定key的值,如果不存在则返回默认值
|
||
return isset($requestData[$key]) ? $requestData[$key] : $default;
|
||
}
|
||
|
||
/**
|
||
* 获取所有请求参数(兼容方法)
|
||
* @return array 所有请求参数
|
||
*/
|
||
protected function getAllRequestParams() {
|
||
return $this->getRequestParam();
|
||
}
|
||
|
||
/**
|
||
* 生成新的token
|
||
*/
|
||
protected function generateToken($riderId, $phone) {
|
||
return md5($riderId . $phone . time());
|
||
}
|
||
} |