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

442 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# API快速测试指南
## 概述
本文档提供认证系统API的快速测试方法适用于开发和调试场景。
## 前置条件
1. **启动开发服务器**
```bash
php artisan serve
```
2. **确认数据库数据**
```bash
php artisan db:seed --class=AdminUserSeeder
```
## 测试用户
| 用户类型 | 用户名 | 密码 | 说明 |
|---------|--------|------|------|
| 管理员 | admin | 123456 | 超级管理员权限 |
| 测试用户 | test | 123456 | 普通用户权限 |
## 接口测试 (cURL)
### 1. 登录获取Token
```bash
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": "测试设备"
}'
```
**成功响应示例**:
```json
{
"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. 获取用户信息
```bash
# 替换 YOUR_TOKEN 为实际的Token
curl -X GET http://localhost:8000/admin/auth/me \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Accept: application/json"
```
### 3. 获取设备列表
```bash
curl -X GET http://localhost:8000/admin/auth/devices \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Accept: application/json"
```
### 4. 刷新Token
```bash
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. 登出当前设备
```bash
curl -X POST http://localhost:8000/admin/auth/logout \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Accept: application/json"
```
### 6. 登出所有设备
```bash
curl -X POST http://localhost:8000/admin/auth/logout-all \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Accept: application/json"
```
### 7. 访问仪表盘
```bash
curl -X GET http://localhost:8000/admin/dashboard \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Accept: application/json"
```
## 接口测试 (JavaScript)
### 浏览器控制台测试
```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=== 测试完成 ===');
}
```
### 完整测试示例
```html
<!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`
- 确认数据库连接是否正常
## 性能测试
### 并发登录测试
```bash
# 使用ab工具进行并发测试
ab -n 100 -c 10 -p login.json -T application/json http://localhost:8000/admin/auth/login
```
其中 `login.json` 文件内容:
```json
{
"username": "admin",
"password": "123456",
"device_name": "压力测试"
}
```
---
**注意**: 本测试指南仅用于开发环境生产环境请使用HTTPS并配置适当的安全措施。