12 KiB
12 KiB
API快速测试指南
概述
本文档提供认证系统API的快速测试方法,适用于开发和调试场景。
前置条件
-
启动开发服务器
php artisan serve -
确认数据库数据
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并配置适当的安全措施。