本文目录导读:

我来详细说明在PHP项目中实现JWT(JSON Web Token)的几种方式。
使用第三方库(推荐)
Firebase JWT 库(最常用)
安装:
composer require firebase/php-jwt
基础使用:
<?php
require_once 'vendor/autoload.php';
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
class JwtService {
private $key;
private $algorithm = 'HS256';
public function __construct() {
// 密钥存储在环境变量中
$this->key = getenv('JWT_SECRET_KEY');
}
// 生成 Token
public function generateToken($userId, $expireTime = 3600) {
$payload = [
'iss' => 'your-app-name', // 签发者
'iat' => time(), // 签发时间
'exp' => time() + $expireTime, // 过期时间
'sub' => $userId, // 用户ID
'role' => 'user' // 可以添加自定义字段
];
return JWT::encode($payload, $this->key, $this->algorithm);
}
// 验证 Token
public function validateToken($token) {
try {
$decoded = JWT::decode($token, new Key($this->key, $this->algorithm));
return (array) $decoded;
} catch (\Exception $e) {
// 处理各种异常
throw new \Exception('Token验证失败:' . $e->getMessage());
}
}
// 刷新 Token
public function refreshToken($oldToken) {
$payload = $this->validateToken($oldToken);
// 生成新的Token
return $this->generateToken($payload['sub']);
}
}
完整实现示例
用户登录并生成Token
<?php
// login.php
require_once 'vendor/autoload.php';
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
class AuthController {
private $jwtKey;
public function __construct() {
$this->jwtKey = 'your-secret-key-here';
}
// 用户登录
public function login($username, $password) {
// 验证用户(示例简化)
$user = $this->authenticateUser($username, $password);
if (!$user) {
http_response_code(401);
echo json_encode(['error' => '登录失败']);
return;
}
// 生成Token
$token = $this->createToken($user);
echo json_encode([
'token' => $token,
'user' => [
'id' => $user['id'],
'username' => $user['username']
]
]);
}
private function createToken($user) {
$payload = [
'iss' => 'my-api',
'iat' => time(),
'exp' => time() + (7 * 24 * 60 * 60), // 7天过期
'user_id' => $user['id'],
'username' => $user['username'],
'role' => $user['role']
];
// 可选:添加 Refresh Token
$refreshToken = bin2hex(random_bytes(32));
return [
'access_token' => JWT::encode($payload, $this->jwtKey, 'HS256'),
'refresh_token' => $refreshToken,
'token_type' => 'Bearer',
'expires_in' => 7 * 24 * 60 * 60
];
}
// 验证请求中的Token
public function authenticateRequest() {
$headers = getallheaders();
$authHeader = $headers['Authorization'] ?? '';
if (empty($authHeader) || !str_starts_with($authHeader, 'Bearer ')) {
http_response_code(401);
echo json_encode(['error' => '缺少认证信息']);
exit;
}
$token = substr($authHeader, 7);
try {
$decoded = JWT::decode($token, new Key($this->jwtKey, 'HS256'));
return (array) $decoded;
} catch (\Exception $e) {
http_response_code(401);
echo json_encode(['error' => 'Token无效或已过期']);
exit;
}
}
}
中间件实现
<?php
// middleware.php
class JwtMiddleware {
private $jwtService;
private $excludedPaths = ['/login', '/register'];
public function __construct($jwtService) {
$this->jwtService = $jwtService;
}
// 路由中间件
public function handle($requestPath) {
// 排除不需要认证的路径
if (in_array($requestPath, $this->excludedPaths)) {
return true;
}
$token = $this->getBearerToken();
if (!$token) {
$this->unauthorizedResponse('缺少Token');
}
try {
$payload = $this->jwtService->validateToken($token);
// 将用户信息保存到请求中
$_REQUEST['user'] = $payload;
return true;
} catch (\Exception $e) {
$this->unauthorizedResponse($e->getMessage());
}
}
private function getBearerToken() {
$headers = getallheaders();
$authHeader = $headers['Authorization'] ?? '';
if (preg_match('/Bearer\s(\S+)/', $authHeader, $matches)) {
return $matches[1];
}
return null;
}
private function unauthorizedResponse($message) {
http_response_code(401);
echo json_encode(['error' => $message]);
exit;
}
}
使用其他JWT库
Lcobucci JWT(另一个流行选择)
composer require lcobucci/jwt
<?php
require_once 'vendor/autoload.php';
use Lcobucci\JWT\Configuration;
use Lcobucci\JWT\Signer\Hmac\Sha256;
use Lcobucci\JWT\Signer\Key\InMemory;
class JwtHandler {
private $config;
public function __construct() {
$this->config = Configuration::forSymmetricSigner(
new Sha256(),
InMemory::base64Encoded('your-base64-encoded-secret')
);
}
// 生成Token
public function createToken($userId) {
$now = new DateTimeImmutable();
$token = $this->config->builder()
->issuedBy('your-app')
->permittedFor('your-client')
->identifiedBy(bin2hex(random_bytes(16)))
->issuedAt($now)
->canOnlyBeUsedAfter($now)
->expiresAt($now->modify('+1 hour'))
->withClaim('user_id', $userId)
->getToken($this->config->signer(), $this->config->signingKey());
return $token->toString();
}
// 验证Token
public function validateToken($tokenString) {
try {
$token = $this->config->parser()->parse($tokenString);
// 验证签名
if (!$token->verify($this->config->signer(), $this->config->signingKey())) {
throw new \Exception('签名验证失败');
}
// 检查是否过期
if ($token->isExpired(new DateTimeImmutable())) {
throw new \Exception('Token已过期');
}
return $token->claims();
} catch (\Exception $e) {
throw $e;
}
}
}
安全建议
密钥管理
<?php
// config.php
define('JWT_SECRET', getenv('JWT_SECRET'));
define('JWT_ALGORITHM', 'HS256');
define('JWT_EXPIRY', 3600); // 1小时
// .env 文件
// JWT_SECRET=your-256-bit-secret-key-here
Refresh Token 实现
<?php
class RefreshTokenService {
private $db; // 数据库连接
// 保存Refresh Token到数据库
public function saveRefreshToken($userId, $refreshToken, $expiresAt) {
$sql = "INSERT INTO refresh_tokens (user_id, token, expires_at)
VALUES (?, ?, ?)";
$stmt = $this->db->prepare($sql);
$stmt->execute([$userId, $refreshToken, $expiresAt]);
}
// 使用Refresh Token获取新的Access Token
public function refreshAccessToken($refreshToken) {
// 验证Refresh Token
$token = $this->getValidRefreshToken($refreshToken);
if (!$token) {
throw new \Exception('Refresh Token无效');
}
// 删除旧的Refresh Token
$this->deleteRefreshToken($refreshToken);
// 生成新的Access Token和Refresh Token
$newAccessToken = $this->generateAccessToken($token['user_id']);
$newRefreshToken = $this->generateRefreshToken();
// 保存新的Refresh Token
$this->saveRefreshToken(
$token['user_id'],
$newRefreshToken,
date('Y-m-d H:i:s', strtotime('+30 days'))
);
return [
'access_token' => $newAccessToken,
'refresh_token' => $newRefreshToken
];
}
}
前端使用示例
// 前端请求示例
fetch('https://api.example.com/protected-endpoint', {
method: 'GET',
headers: {
'Authorization': `Bearer ${localStorage.getItem('access_token')}`,
'Content-Type': 'application/json'
}
})
.then(response => {
if (response.status === 401) {
// Token过期,尝试刷新
return refreshToken();
}
return response.json();
});
完整项目结构建议
project/
├── composer.json
├── .env
├── config/
│ └── jwt.php
├── src/
│ ├── JwtService.php
│ ├── JwtMiddleware.php
│ └── AuthController.php
└── vendor/
这就是PHP实现JWT的完整方案,建议使用成熟的第三方库(如 firebase/php-jwt),并注意密钥安全和Token有效期管理。
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播