讲座主题:在PHP中使用JWT实现跨域资源共享(CORS)
开场白
各位听众朋友们,大家好!今天我们要聊一个非常有趣的话题——如何在PHP中使用JWT(JSON Web Token)来实现跨域资源共享(CORS)。如果你是一个前端开发者,可能会经常遇到这样的问题:为什么我的AJAX请求总是被浏览器拦住?如果你是一个后端开发者,可能会问:为什么我的API明明写得没问题,却总报403或500错误?
别急,这些问题的答案就在今天的讲座中。我们将以轻松诙谐的方式,深入探讨JWT和CORS的结合之道。准备好了吗?让我们开始吧!
第一讲:什么是CORS?
CORS(Cross-Origin Resource Sharing)是浏览器的一种安全机制,用于限制网页从不同源加载资源。简单来说,如果你的前端页面运行在http://example.com
,而你的API运行在http://api.example.com
,浏览器会认为这是两个不同的源,因此会阻止前端直接访问后端。
浏览器是如何工作的?
当浏览器检测到跨域请求时,它会先发送一个“预检请求”(OPTIONS方法),询问服务器是否允许该请求。如果服务器响应允许,浏览器才会继续发送实际的请求。
第二讲:什么是JWT?
JWT(JSON Web Token)是一种开放标准(RFC 7519),用于在各方之间安全地传输信息。它的结构非常简单,由三部分组成:Header、Payload和Signature。
JWT = Header.Payload.Signature
- Header:描述令牌的类型和签名算法。
- Payload:包含声明(Claims),例如用户ID、角色等。
- Signature:用于验证令牌的真实性。
JWT的优点
- 轻量级:体积小,适合在网络中传输。
- 自包含:所有信息都在令牌中,无需查询数据库。
- 安全性高:通过签名防止篡改。
第三讲:JWT与CORS的结合
现在我们来解决一个问题:如何在PHP中使用JWT来处理CORS请求?答案其实很简单,就是让服务器在响应中添加适当的CORS头,并验证JWT的有效性。
步骤1:设置CORS头
在PHP中,我们可以使用header()
函数来设置CORS头。以下是一个简单的例子:
<?php
header("Access-Control-Allow-Origin: *"); // 允许所有来源
header("Access-Control-Allow-Methods: GET, POST, OPTIONS"); // 允许的HTTP方法
header("Access-Control-Allow-Headers: Content-Type, Authorization"); // 允许的自定义头
// 如果是预检请求,直接返回200状态码
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
http_response_code(200);
exit;
}
?>
步骤2:验证JWT
接下来,我们需要验证客户端发送的JWT是否有效。假设客户端将JWT放在Authorization
头中,格式为Bearer <token>
。以下是验证JWT的代码:
<?php
function verifyJWT($token, $secretKey) {
try {
$decoded = FirebaseJWTJWT::decode($token, $secretKey, ['HS256']);
return (array)$decoded;
} catch (Exception $e) {
return false;
}
}
$authHeader = $_SERVER['HTTP_AUTHORIZATION'] ?? '';
if (strpos($authHeader, 'Bearer ') === 0) {
$token = substr($authHeader, 7); // 去掉"Bearer "前缀
$user = verifyJWT($token, 'your-secret-key');
if ($user) {
echo json_encode(['message' => 'Token is valid', 'user' => $user]);
} else {
http_response_code(401);
echo json_encode(['error' => 'Invalid token']);
}
} else {
http_response_code(401);
echo json_encode(['error' => 'Missing token']);
}
?>
步骤3:生成JWT
为了让客户端能够获取JWT,我们需要提供一个登录接口。以下是生成JWT的代码:
<?php
function generateJWT($payload, $secretKey) {
return FirebaseJWTJWT::encode($payload, $secretKey, 'HS256');
}
$username = $_POST['username'] ?? '';
$password = $_POST['password'] ?? '';
if ($username === 'admin' && $password === 'password') {
$payload = [
'iss' => 'http://api.example.com',
'sub' => 'admin',
'iat' => time(),
'exp' => time() + 3600
];
$token = generateJWT($payload, 'your-secret-key');
echo json_encode(['token' => $token]);
} else {
http_response_code(401);
echo json_encode(['error' => 'Invalid credentials']);
}
?>
第四讲:总结与注意事项
今天我们学习了如何在PHP中使用JWT来处理CORS请求。以下是几个关键点:
- CORS头设置:确保服务器响应中包含正确的CORS头。
- JWT验证:使用库(如
firebase/php-jwt
)来验证JWT的有效性。 - 安全性:永远不要在JWT中存储敏感信息,例如密码。
注意事项
- CORS头的安全性:尽量避免使用
*
作为Access-Control-Allow-Origin
,而是指定具体的域名。 - JWT过期时间:合理设置JWT的过期时间,避免长期有效的令牌。
- HTTPS:始终使用HTTPS来保护JWT的传输。
结语
好了,今天的讲座就到这里。希望你对JWT和CORS有了更深入的理解。如果你有任何问题,欢迎在评论区留言!下次见啦,拜拜~