本文目录导读:

在PHP API开发中,权限控制是一个核心的安全问题,常见的控制方式包括以下几种,从简单到复杂:
基于角色的访问控制 (RBAC)
这是最基础的权限控制方式。
数据库设计
-- 用户表
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) UNIQUE,
password VARCHAR(255),
role_id INT
);
-- 角色表
CREATE TABLE roles (
id INT PRIMARY KEY,
role_name VARCHAR(50) -- admin, user, guest
);
-- 权限表
CREATE TABLE permissions (
id INT PRIMARY KEY,
permission_name VARCHAR(100) -- user.create, user.delete, article.edit
);
PHP实现示例
class ApiAuth {
private $rolePermissions = [
'admin' => ['user.create', 'user.delete', 'article.edit', 'article.delete'],
'editor' => ['article.edit', 'article.create'],
'user' => ['article.read']
];
public function checkPermission($userId, $requiredPermission) {
$user = $this->getUser($userId);
$role = $user['role'];
if (!isset($this->rolePermissions[$role])) {
return false;
}
return in_array($requiredPermission, $this->rolePermissions[$role]);
}
}
// 在API路由中使用
$auth = new ApiAuth();
if (!$auth->checkPermission($_GET['user_id'], 'article.edit')) {
http_response_code(403);
echo json_encode(['error' => '无权限']);
exit;
}
JWT (JSON Web Token) 鉴权
这是目前最流行的API权限控制方式。
实现步骤
// 1. 生成JWT Token
use Firebase\JWT\JWT;
class JwtAuth {
private $secretKey = 'your-secret-key';
private $algorithm = 'HS256';
public function generateToken($userData) {
$payload = [
'iss' => 'your-domain.com', // 签发者
'iat' => time(), // 签发时间
'exp' => time() + 7200, // 过期时间2小时
'user_id' => $userData['id'],
'role' => $userData['role'],
'permissions' => $userData['permissions']
];
return JWT::encode($payload, $this->secretKey, $this->algorithm);
}
public function validateToken($token) {
try {
$decoded = JWT::decode($token, $this->secretKey, [$this->algorithm]);
return (array) $decoded;
} catch (Exception $e) {
return false;
}
}
}
// 2. 中间件检查权限
function apiMiddleware($requiredPermission) {
$headers = getallheaders();
$token = str_replace('Bearer ', '', $headers['Authorization'] ?? '');
$jwt = new JwtAuth();
$userData = $jwt->validateToken($token);
if (!$userData) {
http_response_code(401);
echo json_encode(['error' => '未授权']);
exit;
}
// 检查权限
if (!in_array($requiredPermission, $userData['permissions'])) {
http_response_code(403);
echo json_encode(['error' => '权限不足']);
exit;
}
return $userData;
}
// 3. 在路由中使用
Route::get('/api/articles', function() {
$userData = apiMiddleware('article.read');
// 继续处理请求...
});
Route::post('/api/articles', function() {
$userData = apiMiddleware('article.create');
// 继续处理请求...
});
OAuth 2.0 授权框架
适用于第三方应用接入的场景。
简化的OAuth实现
class OAuthServer {
private $clients = [
'app1' => ['secret' => 'sec123', 'redirect_uri' => 'http://app1.com/callback']
];
// 授权码模式
public function authorize($clientId, $redirectUri, $scope) {
// 验证客户端
if (!isset($this->clients[$clientId])) {
throw new Exception('无效客户端');
}
// 生成授权码
$authCode = bin2hex(random_bytes(16));
// 保存授权码到数据库
$this->saveAuthCode($authCode, $clientId, $scope);
// 重定向回客户端
header("Location: {$redirectUri}?code={$authCode}");
}
// 换取Access Token
public function getAccessToken($code, $clientId, $clientSecret) {
// 验证客户端凭证
if ($this->clients[$clientId]['secret'] !== $clientSecret) {
throw new Exception('无效凭证');
}
// 验证授权码
$authData = $this->validateAuthCode($code);
// 生成Access Token
$accessToken = bin2hex(random_bytes(32));
$refreshToken = bin2hex(random_bytes(32));
return [
'access_token' => $accessToken,
'refresh_token' => $refreshToken,
'expires_in' => 3600,
'scope' => $authData['scope']
];
}
}
细粒度权限控制 (ACL)
适用于复杂权限需求。
PHP实现
class AclController {
private $acl = [];
public function __construct() {
// 定义用户资源的权限
$this->acl = [
'user_id_1' => [
'resource_1' => ['read', 'write'],
'resource_2' => ['read']
],
'user_id_2' => [
'resource_1' => ['read']
]
];
}
public function checkAccess($userId, $resourceId, $action) {
if (!isset($this->acl[$userId])) {
return false;
}
if (!isset($this->acl[$userId][$resourceId])) {
return false;
}
return in_array($action, $this->acl[$userId][$resourceId]);
}
public function addPermission($userId, $resourceId, $actions) {
if (!isset($this->acl[$userId])) {
$this->acl[$userId] = [];
}
$this->acl[$userId][$resourceId] = $actions;
}
}
中间件实现模式
Laravel风格中间件
class PermissionMiddleware {
private $permissionMap = [
'GET' => 'read',
'POST' => 'create',
'PUT' => 'update',
'DELETE' => 'delete'
];
public function handle($request, $next) {
$method = $request->getMethod();
$resource = $request->getPathInfo();
$action = $this->permissionMap[$method];
// 从Token获取用户信息
$user = $this->getUserFromToken($request);
if (!$this->hasPermission($user, $resource, $action)) {
return response()->json([
'error' => '权限不足',
'code' => 403
], 403);
}
return $next($request);
}
}
最佳实践建议
使用开源库
- PHP-JWT:
firebase/php-jwt - OAuth2:
thephpleague/oauth2-server - ACL: 自行实现或使用
zendframework/zend-permissions-acl
安全注意事项
// 1. 使用HTTPS
// 2. Token存储在header中,不在URL传递
$token = $_SERVER['HTTP_AUTHORIZATION'] ?? '';
// 3. Token定期轮换
if ($token['exp'] < time()) {
// 刷新token
}
// 4. 记录操作日志
$logger->info("User {id} accessed {resource}", [
'id' => $userId,
'resource' => $resource
]);
性能优化
// 1. 缓存权限数据
$cacheKey = "permissions:{$userId}";
$permissions = $cache->get($cacheKey);
if (!$permissions) {
$permissions = $db->query("SELECT * FROM user_permissions WHERE user_id = ?", [$userId]);
$cache->set($cacheKey, $permissions, 3600);
}
// 2. 使用Redis存储Token
$redis->set("token:{$accessToken}", json_encode($userData), 3600);
选择哪种方式取决于你的项目规模和安全需求,对小项目使用JWT+RBAC就足够了,大型系统可能需要OAuth2.0或更复杂的权限模型。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播