下面是一个原生 PHP Token 鉴权示例,包含登录、Bearer Token 校验和受保护接口。复制为 auth-api.php 即可运行。
<?php
declare(strict_types=1);
header('Content-Type: application/json; charset=utf-8');
const SECRET_KEY = 'replace-with-a-random-secret-key';
$users = [
'admin' => password_hash('123456', PASSWORD_DEFAULT),
];
function response(int $code, string $message, $data = null, int $status = 200): void
{
http_response_code($status);
echo json_encode(compact('code', 'message', 'data'), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
exit;
}
function input(): array
{
$data = json_decode(file_get_contents('php://input') ?: '{}', true);
return is_array($data) ? $data : [];
}
function base64url(string $value): string
{
return rtrim(strtr(base64_encode($value), '+/', '-_'), '=');
}
function sign(array $payload): string
{
$body = base64url(json_encode($payload, JSON_UNESCAPED_SLASHES));
$signature = base64url(hash_hmac('sha256', $body, SECRET_KEY, true));
return $body . '.' . $signature;
}
function verify_token(string $token): array
{
[$body, $signature] = array_pad(explode('.', $token, 2), 2, '');
if ($body === '' || $signature === '') {
response(401, 'Token 格式错误', null, 401);
}
$expected = base64url(hash_hmac('sha256', $body, SECRET_KEY, true));
if (!hash_equals($expected, $signature)) {
response(401, 'Token 无效', null, 401);
}
$payload = json_decode(base64_decode(strtr($body, '-_', '+/')), true);
if (!is_array($payload) || ($payload['exp'] ?? 0) < time()) {
response(401, 'Token 已过期', null, 401);
}
return $payload;
}
function current_user(): array
{
$header = $_SERVER['HTTP_AUTHORIZATION'] ?? '';
if (!preg_match('/^Bearers+(.+)$/i', $header, $m)) {
response(401, '请先登录', null, 401);
}
return verify_token($m[1]);
}
$method = $_SERVER['REQUEST_METHOD'] ?? 'GET';
$path = parse_url($_SERVER['REQUEST_URI'] ?? '/', PHP_URL_PATH);
if ($method === 'POST' && $path === '/api/login') {
global $users;
$data = input();
$username = (string)($data['username'] ?? '');
$password = (string)($data['password'] ?? '');
if (!isset($users[$username]) || !password_verify($password, $users[$username])) {
response(401, '账号或密码错误', null, 401);
}
response(0, '登录成功', [
'token' => sign([
'uid' => 1,
'username' => $username,
'exp' => time() + 7200,
]),
]);
}
if ($method === 'GET' && $path === '/api/profile') {
$user = current_user();
response(0, 'ok', [
'uid' => $user['uid'],
'username' => $user['username'],
]);
}
response(404, '接口不存在', null, 404); 运行方式:
# 启动
php -S 127.0.0.1:8000 auth-api.php
# 登录获取 token
TOKEN=$(curl -s -X POST http://127.0.0.1:8000/api/login -H 'Content-Type: application/json' -d '{"username":"admin","password":"123456"}' | php -r '$j=json_decode(stream_get_contents(STDIN),true); echo $j["data"]["token"] ?? "";')
# 访问受保护接口
curl http://127.0.0.1:8000/api/profile -H "Authorization: Bearer $TOKEN"