study-api-v2/docs/API快速测试指南.md

12 KiB
Raw Permalink Blame History

API快速测试指南

概述

本文档提供认证系统API的快速测试方法适用于开发和调试场景。

前置条件

  1. 启动开发服务器

    php artisan serve
    
  2. 确认数据库数据

    php artisan db:seed --class=AdminUserSeeder
    

测试用户

用户类型 用户名 密码 说明
管理员 admin 123456 超级管理员权限
测试用户 test 123456 普通用户权限

接口测试 (cURL)

1. 登录获取Token

curl -X POST http://localhost:8000/admin/auth/login \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "username": "admin",
    "password": "123456",
    "device_name": "测试设备"
  }'

成功响应示例:

{
  "success": true,
  "data": {
    "user": {
      "id": 1,
      "username": "admin",
      "nickname": "超级管理员",
      "email": "admin@example.com"
    },
    "token": {
      "access_token": "1|xxxxxxxxxxxx",
      "token_type": "Bearer"
    }
  },
  "code": 200,
  "message": "登录成功"
}

2. 获取用户信息

# 替换 YOUR_TOKEN 为实际的Token
curl -X GET http://localhost:8000/admin/auth/me \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Accept: application/json"

3. 获取设备列表

curl -X GET http://localhost:8000/admin/auth/devices \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Accept: application/json"

4. 刷新Token

curl -X POST http://localhost:8000/admin/auth/refresh \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "device_name": "刷新后的设备"
  }'

5. 登出当前设备

curl -X POST http://localhost:8000/admin/auth/logout \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Accept: application/json"

6. 登出所有设备

curl -X POST http://localhost:8000/admin/auth/logout-all \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Accept: application/json"

7. 访问仪表盘

curl -X GET http://localhost:8000/admin/dashboard \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Accept: application/json"

接口测试 (JavaScript)

浏览器控制台测试

// 1. 登录
async function testLogin() {
  const response = await fetch('http://localhost:8000/admin/auth/login', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Accept': 'application/json'
    },
    body: JSON.stringify({
      username: 'admin',
      password: '123456',
      device_name: 'Browser Test'
    })
  });
  
  const data = await response.json();
  console.log('登录结果:', data);
  
  if (data.success) {
    // 保存Token到localStorage
    localStorage.setItem('token', data.data.token.access_token);
    console.log('Token已保存到localStorage');
  }
  
  return data;
}

// 2. 测试认证接口
async function testAuthAPI() {
  const token = localStorage.getItem('token');
  if (!token) {
    console.error('请先登录获取Token');
    return;
  }
  
  const response = await fetch('http://localhost:8000/admin/auth/me', {
    headers: {
      'Authorization': `Bearer ${token}`,
      'Accept': 'application/json'
    }
  });
  
  const data = await response.json();
  console.log('用户信息:', data);
  return data;
}

// 3. 测试登出
async function testLogout() {
  const token = localStorage.getItem('token');
  if (!token) {
    console.error('请先登录获取Token');
    return;
  }
  
  const response = await fetch('http://localhost:8000/admin/auth/logout', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${token}`,
      'Accept': 'application/json'
    }
  });
  
  const data = await response.json();
  console.log('登出结果:', data);
  
  if (data.success) {
    localStorage.removeItem('token');
    console.log('Token已从localStorage清除');
  }
  
  return data;
}

// 运行测试
async function runTests() {
  console.log('=== 开始API测试 ===');
  
  // 测试登录
  console.log('\n1. 测试登录...');
  await testLogin();
  
  // 等待1秒
  await new Promise(resolve => setTimeout(resolve, 1000));
  
  // 测试获取用户信息
  console.log('\n2. 测试获取用户信息...');
  await testAuthAPI();
  
  // 等待1秒
  await new Promise(resolve => setTimeout(resolve, 1000));
  
  // 测试登出
  console.log('\n3. 测试登出...');
  await testLogout();
  
  console.log('\n=== 测试完成 ===');
}

完整测试示例

<!DOCTYPE html>
<html>
<head>
    <title>API测试页面</title>
    <style>
        body { font-family: Arial, sans-serif; padding: 20px; }
        .container { max-width: 800px; margin: 0 auto; }
        .test-section { margin: 20px 0; padding: 15px; border: 1px solid #ddd; }
        button { padding: 10px 15px; margin: 5px; cursor: pointer; }
        pre { background: #f5f5f5; padding: 10px; overflow-x: auto; }
        .success { color: green; }
        .error { color: red; }
    </style>
</head>
<body>
    <div class="container">
        <h1>认证系统API测试</h1>
        
        <div class="test-section">
            <h3>1. 登录测试</h3>
            <button onclick="testLogin()">测试登录</button>
            <div id="loginResult"></div>
        </div>
        
        <div class="test-section">
            <h3>2. 用户信息测试</h3>
            <button onclick="testGetUser()">获取用户信息</button>
            <div id="userResult"></div>
        </div>
        
        <div class="test-section">
            <h3>3. 设备管理测试</h3>
            <button onclick="testGetDevices()">获取设备列表</button>
            <button onclick="testRefreshToken()">刷新Token</button>
            <div id="deviceResult"></div>
        </div>
        
        <div class="test-section">
            <h3>4. 登出测试</h3>
            <button onclick="testLogout()">登出当前设备</button>
            <button onclick="testLogoutAll()">登出所有设备</button>
            <div id="logoutResult"></div>
        </div>
    </div>

    <script>
        const API_BASE = 'http://localhost:8000/admin';
        let currentToken = localStorage.getItem('auth_token');

        function displayResult(elementId, data, isSuccess = true) {
            const element = document.getElementById(elementId);
            element.innerHTML = `<pre class="${isSuccess ? 'success' : 'error'}">${JSON.stringify(data, null, 2)}</pre>`;
        }

        async function apiRequest(url, options = {}) {
            const defaultHeaders = {
                'Content-Type': 'application/json',
                'Accept': 'application/json'
            };

            if (currentToken && !url.includes('/login')) {
                defaultHeaders['Authorization'] = `Bearer ${currentToken}`;
            }

            const response = await fetch(`${API_BASE}${url}`, {
                ...options,
                headers: { ...defaultHeaders, ...options.headers }
            });

            return { response, data: await response.json() };
        }

        async function testLogin() {
            try {
                const { response, data } = await apiRequest('/auth/login', {
                    method: 'POST',
                    body: JSON.stringify({
                        username: 'admin',
                        password: '123456',
                        device_name: 'Web测试'
                    })
                });

                if (data.success) {
                    currentToken = data.data.token.access_token;
                    localStorage.setItem('auth_token', currentToken);
                }

                displayResult('loginResult', data, data.success);
            } catch (error) {
                displayResult('loginResult', { error: error.message }, false);
            }
        }

        async function testGetUser() {
            try {
                const { response, data } = await apiRequest('/auth/me');
                displayResult('userResult', data, data.success);
            } catch (error) {
                displayResult('userResult', { error: error.message }, false);
            }
        }

        async function testGetDevices() {
            try {
                const { response, data } = await apiRequest('/auth/devices');
                displayResult('deviceResult', data, data.success);
            } catch (error) {
                displayResult('deviceResult', { error: error.message }, false);
            }
        }

        async function testRefreshToken() {
            try {
                const { response, data } = await apiRequest('/auth/refresh', {
                    method: 'POST',
                    body: JSON.stringify({
                        device_name: '刷新后的Web设备'
                    })
                });

                if (data.success) {
                    currentToken = data.data.token.access_token;
                    localStorage.setItem('auth_token', currentToken);
                }

                displayResult('deviceResult', data, data.success);
            } catch (error) {
                displayResult('deviceResult', { error: error.message }, false);
            }
        }

        async function testLogout() {
            try {
                const { response, data } = await apiRequest('/auth/logout', {
                    method: 'POST'
                });

                if (data.success) {
                    currentToken = null;
                    localStorage.removeItem('auth_token');
                }

                displayResult('logoutResult', data, data.success);
            } catch (error) {
                displayResult('logoutResult', { error: error.message }, false);
            }
        }

        async function testLogoutAll() {
            try {
                const { response, data } = await apiRequest('/auth/logout-all', {
                    method: 'POST'
                });

                if (data.success) {
                    currentToken = null;
                    localStorage.removeItem('auth_token');
                }

                displayResult('logoutResult', data, data.success);
            } catch (error) {
                displayResult('logoutResult', { error: error.message }, false);
            }
        }

        // 页面加载时显示当前Token状态
        window.onload = function() {
            if (currentToken) {
                console.log('当前Token:', currentToken);
            } else {
                console.log('未登录状态');
            }
        };
    </script>
</body>
</html>

常见错误排查

1. 401 Unauthorized

  • 检查Token是否正确
  • 检查Authorization头格式是否为 Bearer {token}
  • 确认Token是否已过期

2. 404 Not Found

  • 检查路由是否正确注册
  • 运行 php artisan route:list | findstr admin 查看路由列表

3. 422 Validation Error

  • 检查请求参数是否完整
  • 确认Content-Type为application/json

4. 500 Internal Server Error

  • 检查Laravel日志storage/logs/laravel.log
  • 确认数据库连接是否正常

性能测试

并发登录测试

# 使用ab工具进行并发测试
ab -n 100 -c 10 -p login.json -T application/json http://localhost:8000/admin/auth/login

其中 login.json 文件内容:

{
  "username": "admin",
  "password": "123456",
  "device_name": "压力测试"
}

注意: 本测试指南仅用于开发环境生产环境请使用HTTPS并配置适当的安全措施。