叶动文档中心叶动文档中心
叶动官网
使用指南
接口文档
  • 简体中文
  • English
GitHub
叶动官网
使用指南
接口文档
  • 简体中文
  • English
GitHub
  • � 接口文档

    • 接口文档
    • API 认证指南
    • API 使用示例
    • 错误码参考

API 认证指南

本文档详细介绍如何进行 API 认证和授权。

🔐 认证方式

Bearer Token 认证

叶动文档中心 API 使用 Bearer Token 进行认证。您需要在每个请求的 Authorization 头中包含有效的 token。

Authorization: Bearer YOUR_API_TOKEN

获取 API Token

方式一:通过登录接口获取

async function login(email, password) {
  const response = await fetch('/api/auth/login', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      email: email,
      password: password
    })
  });
  
  const data = await response.json();
  
  if (data.code === 200) {
    // 保存 token
    localStorage.setItem('api_token', data.data.token);
    return data.data.token;
  } else {
    throw new Error(data.message);
  }
}

方式二:在管理后台生成

  1. 登录管理后台
  2. 进入 "API 管理" 页面
  3. 点击 "生成新 Token"
  4. 复制生成的 Token

🔑 Token 管理

Token 存储

// 安全存储 Token
class TokenManager {
  static setToken(token) {
    // 生产环境建议使用更安全的存储方式
    localStorage.setItem('api_token', token);
  }
  
  static getToken() {
    return localStorage.getItem('api_token');
  }
  
  static removeToken() {
    localStorage.removeItem('api_token');
  }
  
  static isTokenValid() {
    const token = this.getToken();
    if (!token) return false;
    
    try {
      // 解析 JWT token(如果使用 JWT)
      const payload = JSON.parse(atob(token.split('.')[1]));
      const now = Date.now() / 1000;
      
      return payload.exp > now;
    } catch (error) {
      return false;
    }
  }
}

Token 刷新

async function refreshToken() {
  const refreshToken = localStorage.getItem('refresh_token');
  
  if (!refreshToken) {
    throw new Error('No refresh token available');
  }
  
  const response = await fetch('/api/auth/refresh', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      refresh_token: refreshToken
    })
  });
  
  const data = await response.json();
  
  if (data.code === 200) {
    TokenManager.setToken(data.data.access_token);
    localStorage.setItem('refresh_token', data.data.refresh_token);
    return data.data.access_token;
  } else {
    // 刷新失败,需要重新登录
    TokenManager.removeToken();
    localStorage.removeItem('refresh_token');
    throw new Error('Token refresh failed');
  }
}

🛡️ 权限控制

权限级别

权限级别描述可访问的接口
admin管理员所有接口
user普通用户用户相关接口
readonly只读用户仅查询接口

权限检查

class APIClient {
  constructor(token) {
    this.token = token;
    this.userInfo = null;
  }
  
  async getUserInfo() {
    if (!this.userInfo) {
      const response = await this.request('/api/user/profile');
      this.userInfo = response.data;
    }
    return this.userInfo;
  }
  
  async hasPermission(permission) {
    const userInfo = await this.getUserInfo();
    return userInfo.permissions.includes(permission);
  }
  
  async request(endpoint, options = {}) {
    const headers = {
      'Authorization': `Bearer ${this.token}`,
      'Content-Type': 'application/json',
      ...options.headers
    };
    
    const response = await fetch(endpoint, {
      ...options,
      headers
    });
    
    if (response.status === 401) {
      // Token 过期或无效
      throw new AuthError('Authentication failed');
    }
    
    if (response.status === 403) {
      // 权限不足
      throw new PermissionError('Permission denied');
    }
    
    return response.json();
  }
}

🔒 安全最佳实践

1. Token 安全

// ✅ 推荐:使用 HTTPS
const API_BASE_URL = 'https://api.example.com';

// ❌ 避免:在 URL 中传递 token
// https://api.example.com/users?token=xxx

// ✅ 推荐:在 Header 中传递
headers: {
  'Authorization': 'Bearer ' + token
}

2. Token 过期处理

class AuthenticatedAPIClient {
  async request(endpoint, options = {}) {
    try {
      return await this.makeRequest(endpoint, options);
    } catch (error) {
      if (error.status === 401) {
        // 尝试刷新 token
        try {
          await this.refreshToken();
          return await this.makeRequest(endpoint, options);
        } catch (refreshError) {
          // 刷新失败,跳转到登录页
          this.redirectToLogin();
          throw refreshError;
        }
      }
      throw error;
    }
  }
  
  redirectToLogin() {
    window.location.href = '/login';
  }
}

3. 请求拦截器

// 使用 Axios 拦截器示例
import axios from 'axios';

const apiClient = axios.create({
  baseURL: 'https://api.example.com'
});

// 请求拦截器
apiClient.interceptors.request.use(
  config => {
    const token = TokenManager.getToken();
    if (token) {
      config.headers.Authorization = `Bearer ${token}`;
    }
    return config;
  },
  error => {
    return Promise.reject(error);
  }
);

// 响应拦截器
apiClient.interceptors.response.use(
  response => {
    return response;
  },
  async error => {
    const originalRequest = error.config;
    
    if (error.response?.status === 401 && !originalRequest._retry) {
      originalRequest._retry = true;
      
      try {
        await refreshToken();
        return apiClient(originalRequest);
      } catch (refreshError) {
        TokenManager.removeToken();
        window.location.href = '/login';
        return Promise.reject(refreshError);
      }
    }
    
    return Promise.reject(error);
  }
);

🧪 测试认证

测试 Token 有效性

async function testAuthentication() {
  const token = TokenManager.getToken();
  
  if (!token) {
    console.log('❌ 没有找到 Token');
    return false;
  }
  
  try {
    const response = await fetch('/api/auth/verify', {
      headers: {
        'Authorization': `Bearer ${token}`
      }
    });
    
    if (response.ok) {
      console.log('✅ Token 有效');
      return true;
    } else {
      console.log('❌ Token 无效');
      return false;
    }
  } catch (error) {
    console.log('❌ 验证失败:', error.message);
    return false;
  }
}

模拟认证流程

// 完整的认证流程示例
async function authenticationFlow() {
  try {
    // 1. 检查现有 token
    if (TokenManager.isTokenValid()) {
      console.log('✅ 使用现有 Token');
      return TokenManager.getToken();
    }
    
    // 2. 尝试刷新 token
    try {
      const newToken = await refreshToken();
      console.log('✅ Token 刷新成功');
      return newToken;
    } catch (refreshError) {
      console.log('⚠️ Token 刷新失败,需要重新登录');
    }
    
    // 3. 重新登录
    const email = prompt('请输入邮箱:');
    const password = prompt('请输入密码:');
    
    const token = await login(email, password);
    console.log('✅ 登录成功');
    return token;
    
  } catch (error) {
    console.error('❌ 认证失败:', error.message);
    throw error;
  }
}

📋 常见问题

Q: Token 过期了怎么办?

A: 系统会自动尝试刷新 Token。如果刷新失败,需要重新登录。

Q: 如何检查 Token 是否有效?

A: 可以调用 /api/auth/verify 接口验证 Token 有效性。

Q: Token 丢失了怎么办?

A: 需要重新登录获取新的 Token,或者在管理后台重新生成。

Q: 可以同时使用多个 Token 吗?

A: 可以,但建议为不同的应用或环境使用不同的 Token。

🔗 相关资源

  • API 概述
  • 使用示例
  • 错误码参考
在 GitHub 上编辑此页
Prev
接口文档
Next
API 使用示例