PHP Token 鉴权 API 示例:登录、鉴权中间件和受保护接口 [复制链接]

一级用户组

下面是一个原生 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"
最新回复

请先登录后再回复 登录

uid:4 一级用户组
关注
我与春风皆过客,你携秋水揽星河
发帖 20
评论 0
粉丝 0
关注 0
发新帖
目录
PHP Token 鉴权 API 示例:登录、鉴权中间件和受保护接口