探讨如何在PHP中使用JWT实现跨域资源共享(CORS)

讲座主题:在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的优点

  1. 轻量级:体积小,适合在网络中传输。
  2. 自包含:所有信息都在令牌中,无需查询数据库。
  3. 安全性高:通过签名防止篡改。

第三讲: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请求。以下是几个关键点:

  1. CORS头设置:确保服务器响应中包含正确的CORS头。
  2. JWT验证:使用库(如firebase/php-jwt)来验证JWT的有效性。
  3. 安全性:永远不要在JWT中存储敏感信息,例如密码。

注意事项

  • CORS头的安全性:尽量避免使用*作为Access-Control-Allow-Origin,而是指定具体的域名。
  • JWT过期时间:合理设置JWT的过期时间,避免长期有效的令牌。
  • HTTPS:始终使用HTTPS来保护JWT的传输。

结语

好了,今天的讲座就到这里。希望你对JWT和CORS有了更深入的理解。如果你有任何问题,欢迎在评论区留言!下次见啦,拜拜~

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注