PHP 怎么生成API Token

wen PHP项目 3

本文目录导读:

PHP 怎么生成API Token

  1. 使用 random_bytes()(推荐)
  2. 使用 openssl_random_pseudo_bytes()
  3. 使用 base64_encode() 生成 URL 安全的 Token
  4. 完整的 Token 验证示例
  5. 哈希加密存储 Token
  6. JWT(JSON Web Token)方案
  7. 最佳实践建议

在 PHP 中生成 API Token 有几种常见方法,我来介绍几种可靠的方案:

使用 random_bytes()(推荐)

function generateToken($length = 32) {
    return bin2hex(random_bytes($length));
}
// 使用示例
$token = generateToken(32); // 64字符的十六进制字符串

使用 openssl_random_pseudo_bytes()

function generateTokenOpenSSL($length = 32) {
    return bin2hex(openssl_random_pseudo_bytes($length));
}

使用 base64_encode() 生成 URL 安全的 Token

function generateUrlSafeToken($length = 32) {
    $bytes = random_bytes($length);
    return rtrim(strtr(base64_encode($bytes), '+/', '-_'), '=');
}

完整的 Token 验证示例

class ApiTokenGenerator {
    // 生成 Token
    public static function generate() {
        return bin2hex(random_bytes(32));
    }
    // 生成带过期时间的 Token
    public static function generateWithExpiry($userId, $expiryHours = 24) {
        $token = self::generate();
        $expiry = date('Y-m-d H:i:s', strtotime("+{$expiryHours} hours"));
        // 存储到数据库
        $pdo = new PDO('mysql:host=localhost;dbname=test', 'username', 'password');
        $stmt = $pdo->prepare("INSERT INTO api_tokens (user_id, token, expires_at) VALUES (?, ?, ?)");
        $stmt->execute([$userId, $token, $expiry]);
        return $token;
    }
    // 验证 Token
    public static function validate($token) {
        $pdo = new PDO('mysql:host=localhost;dbname=test', 'username', 'password');
        $stmt = $pdo->prepare("SELECT * FROM api_tokens WHERE token = ? AND expires_at > NOW()");
        $stmt->execute([$token]);
        return $stmt->fetch(PDO::FETCH_ASSOC) !== false;
    }
}
// 使用示例
$token = ApiTokenGenerator::generate();
echo "生成的 Token: " . $token . "\n";
$valid = ApiTokenGenerator::validate($token);
echo "Token 是否有效: " . ($valid ? '是' : '否');

哈希加密存储 Token

function hashToken($token) {
    return hash('sha256', $token);
}
// 存储时(只存储哈希值)
$token = generateToken();
$hashedToken = hashToken($token);
// 将 $hashedToken 存入数据库
// 将 $token 发送给客户端
// 验证时
function verifyToken($token, $hashedTokenFromDB) {
    $hashedInput = hash('sha256', $token);
    return hash_equals($hashedTokenFromDB, $hashedInput);
}

JWT(JSON Web Token)方案

// 使用 Firebase JWT 库(通过 Composer 安装)
// composer require firebase/php-jwt
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
function generateJWT($userId, $secretKey) {
    $payload = [
        'user_id' => $userId,
        'iat' => time(),
        'exp' => time() + (60 * 60 * 24) // 24小时过期
    ];
    return JWT::encode($payload, $secretKey, 'HS256');
}
function validateJWT($token, $secretKey) {
    try {
        $decoded = JWT::decode($token, new Key($secretKey, 'HS256'));
        return (array) $decoded;
    } catch (Exception $e) {
        return false;
    }
}
// 使用示例
$secretKey = 'your-secret-key-here';
$token = generateJWT(123, $secretKey);
$payload = validateJWT($token, $secretKey);

最佳实践建议

  1. 使用 random_bytes():这是 PHP 7+ 中最安全的随机数生成器
  2. Token 长度:至少 32 字节(64 个十六进制字符)
  3. 存储安全:只存储 Token 的哈希值
  4. 设置过期时间:避免 Token 永久有效
  5. HTTPS:始终通过 HTTPS 传输 Token
  6. 速率限制:对 API 请求实施速率限制
// 最终的推荐实现
function generateSecureToken() {
    if (function_exists('random_bytes')) {
        return bin2hex(random_bytes(32)); // 64字符
    } elseif (function_exists('openssl_random_pseudo_bytes')) {
        return bin2hex(openssl_random_pseudo_bytes(32));
    } else {
        // 备用方案
        return hash('sha256', uniqid(mt_rand(), true));
    }
}

选择哪种方案取决于你的具体需求,但对于绝大多数场景,random_bytes() 配合哈希存储就是很好的选择。

抱歉,评论功能暂时关闭!