热土用户开发者文档

欢迎使用热土用户开发者文档。本文档将帮助您了解如何集成热土用户系统到您的应用中,包括API调用、Token管理和软件认证流程。

注意: 所有API请求都需要通过我们提供的第三方API代理进行调用,代理地址为 https://appapi.rtstudio.top

概览

热土用户系统提供了一套完整的用户认证和授权机制,支持第三方应用通过Token进行身份验证和授权。主要功能包括:

API参考

第三方API提供了以下端点:

POST /verify-software-token

验证软件登录Token的有效性

请求参数:
参数名 类型 必填 描述
token string 软件登录Token
响应示例:
{"success": true, "data": {"id": 1, "name": "测试软件", "developer": "测试开发者"}}

POST /verify-access-token

验证用户授权Token的有效性

请求参数:
参数名 类型 必填 描述
token string 用户授权Token
响应示例:
{"success": true, "data": {"id": 1, "user_id": 1, "software_id": 1, "access_token": "...", "expires_at": "2027-03-22T12:00:00Z"}}

POST /get-user-by-token

根据用户授权Token获取用户信息

请求参数:
参数名 类型 必填 描述
token string 用户授权Token
响应示例:
{"success": true, "data": {"id": 1, "uuid": "...", "username": "testuser", "email": "test@example.com", "email_verified": true, "is_beta_user": false}}

POST /data-segments

创建数据段

请求参数:
参数名 类型 必填 描述
email string 用户邮箱
token string 用户授权Token
name string 数据段名称
content string 数据段内容
响应示例:
{"success": true, "message": "数据段创建成功", "data": {"id": 1, "name": "user_settings", "content": "{\"theme\": \"dark\", \"language\": \"zh-CN\"}"}}

PUT /data-segments

修改数据段

请求参数:
参数名 类型 必填 描述
email string 用户邮箱
token string 用户授权Token
name string 数据段名称
content string 数据段内容
响应示例:
{"success": true, "message": "数据段更新成功", "data": {"name": "user_settings", "content": "{\"theme\": \"light\", \"language\": \"zh-CN\"}"}}

DELETE /data-segments

删除数据段

请求参数:
参数名 类型 必填 描述
email string 用户邮箱
token string 用户授权Token
name string 数据段名称
响应示例:
{"success": true, "message": "数据段删除成功"}

POST /data-segments/read

读取数据段

请求参数:
参数名 类型 必填 描述
email string 用户邮箱
token string 用户授权Token
name string 数据段名称
响应示例:
{"success": true, "message": "数据段读取成功", "data": {"id": 1, "name": "user_settings", "content": "{\"theme\": \"dark\", \"language\": \"zh-CN\"}", "created_at": "2026-03-22T12:00:00Z", "updated_at": "2026-03-22T12:00:00Z"}}

Token授权流程

热土用户系统支持两种类型的软件授权:

1. 已认证软件授权流程

已认证软件是指通过热土工作室审核的软件,具有更高的安全性和可信度。

  1. 软件开发者向热土工作室申请软件认证,获取软件Token
  2. 软件启动时,生成安全的state参数
  3. 软件构造登录链接并打开浏览器:https://apilogin.rtstudio.top/?port=${本地端口}&type=token&v=${软件Token}&state=${state}
  4. 用户在浏览器中确认登录,输入账号密码
  5. 服务器验证用户凭据和软件Token
  6. 服务器生成用户授权Token并返回给软件
  7. 软件使用授权Token调用API获取用户信息

2. 未认证软件授权流程

未认证软件是指尚未通过热土工作室审核的软件,用户登录时会收到安全警告。

  1. 软件启动时,生成安全的state参数
  2. 软件构造登录链接并打开浏览器:https://apilogin.rtstudio.top/?port=${本地端口}&type=name&v=${软件名称}&state=${state}
  3. 用户在浏览器中确认登录,输入账号密码
  4. 服务器验证用户凭据
  5. 服务器生成用户授权Token并返回给软件
  6. 软件使用授权Token调用API获取用户信息

3. 完整的登录流程实现

以下是实现完整登录流程的详细步骤:

步骤1:启动本地Web服务器

软件需要在本地启动一个Web服务器,用于接收登录结果回调。

const http = require('http');
const url = require('url');

// 生成随机端口
const PORT = 3456; // 可以使用随机端口

// 启动本地服务器
const server = http.createServer((req, res) => {
    const parsedUrl = url.parse(req.url, true);
    const query = parsedUrl.query;
    
    // 处理登录回调
    if (parsedUrl.pathname === '/') {
        if (query.type === 'success') {
            // 登录成功,获取token
            const token = query.v;
            const state = query.state;
            
            // 验证state参数,防止CSRF攻击
            if (state === expectedState) {
                console.log('登录成功,获取到token:', token);
                // 保存token并使用它调用API
                useAccessToken(token);
            } else {
                console.error('State参数验证失败,可能是CSRF攻击');
            }
        } else if (query.type === 'error') {
            // 登录失败
            const error = query.v;
            console.error('登录失败:', error);
        }
        
        // 返回成功页面
        res.writeHead(200, { 'Content-Type': 'text/html' });
        res.end('

登录完成,请关闭此窗口

'); } }); server.listen(PORT, () => { console.log(`本地服务器已启动,监听端口: ${PORT}`); // 启动登录流程 startLoginFlow(PORT); });

步骤2:构造登录链接并打开浏览器

软件需要构造登录链接并打开浏览器,引导用户登录。

const { exec } = require('child_process');

// 生成安全的state参数
function generateState() {
    return require('crypto').randomBytes(16).toString('hex');
}

// 启动登录流程
function startLoginFlow(port) {
    const state = generateState();
    expectedState = state; // 保存state用于验证
    
    // 构造登录链接
    const loginUrl = `https://apilogin.rtstudio.top/?port=${port}&type=token&v=${softwareToken}&state=${state}`;
    
    // 打开浏览器
    if (process.platform === 'win32') {
        exec(`start ${loginUrl}`);
    } else if (process.platform === 'darwin') {
        exec(`open ${loginUrl}`);
    } else {
        exec(`xdg-open ${loginUrl}`);
    }
    
    console.log('已打开浏览器,请登录');
}

步骤3:使用获取到的token调用API

登录成功后,软件可以使用获取到的token调用API获取用户信息。

const axios = require('axios');

// 使用获取到的token
async function useAccessToken(token) {
    try {
        // 验证token有效性
        const verifyResponse = await axios.post('https://appapi.rtstudio.top/verify-access-token', {
            token: token
        });
        
        if (verifyResponse.data.success) {
            console.log('Token验证成功');
            
            // 获取用户信息
            const userResponse = await axios.post('https://appapi.rtstudio.top/get-user-by-token', {
                token: token
            });
            
            if (userResponse.data.success) {
                console.log('获取用户信息成功:', userResponse.data.data);
                // 使用用户信息
                console.log('欢迎,', userResponse.data.data.username);
            } else {
                console.error('获取用户信息失败:', userResponse.data.message);
            }
        } else {
            console.error('Token验证失败:', verifyResponse.data.message);
        }
    } catch (error) {
        console.error('API调用失败:', error);
    }
}

完整示例代码

const http = require('http');
const url = require('url');
const { exec } = require('child_process');
const axios = require('axios');

// 软件配置
const softwareToken = 'your_software_token'; // 已认证软件的token
let expectedState = '';

// 生成安全的state参数
function generateState() {
    return require('crypto').randomBytes(16).toString('hex');
}

// 启动本地服务器
function startLocalServer() {
    const PORT = 3456;
    
    const server = http.createServer((req, res) => {
        const parsedUrl = url.parse(req.url, true);
        const query = parsedUrl.query;
        
        if (parsedUrl.pathname === '/') {
            if (query.type === 'success') {
                const token = query.v;
                const state = query.state;
                
                if (state === expectedState) {
                    console.log('登录成功,获取到token:', token);
                    useAccessToken(token);
                } else {
                    console.error('State参数验证失败');
                }
            } else if (query.type === 'error') {
                console.error('登录失败:', query.v);
            }
            
            res.writeHead(200, { 'Content-Type': 'text/html' });
            res.end('

登录完成,请关闭此窗口

'); // 关闭服务器 setTimeout(() => { server.close(); console.log('本地服务器已关闭'); }, 1000); } }); server.listen(PORT, () => { console.log(`本地服务器已启动,监听端口: ${PORT}`); openLoginPage(PORT); }); } // 打开登录页面 function openLoginPage(port) { const state = generateState(); expectedState = state; const loginUrl = `https://apilogin.rtstudio.top/?port=${port}&type=token&v=${softwareToken}&state=${state}`; if (process.platform === 'win32') { exec(`start ${loginUrl}`); } else if (process.platform === 'darwin') { exec(`open ${loginUrl}`); } else { exec(`xdg-open ${loginUrl}`); } console.log('已打开浏览器,请登录'); } // 使用获取到的token async function useAccessToken(token) { try { const userResponse = await axios.post('https://appapi.rtstudio.top/get-user-by-token', { token: token }); if (userResponse.data.success) { console.log('获取用户信息成功:'); console.log('用户名:', userResponse.data.data.username); console.log('邮箱:', userResponse.data.data.email); console.log('是否Beta用户:', userResponse.data.data.is_beta_user); } else { console.error('获取用户信息失败:', userResponse.data.message); } } catch (error) { console.error('API调用失败:', error); } } // 启动登录流程 startLocalServer();

软件认证流程

如果您希望您的软件成为已认证软件,需要按照以下流程申请:

  1. 准备以下材料:
    • 软件名称
    • 软件开发者信息
    • 软件功能描述
    • 软件截图
    • 软件下载链接(如果有)
  2. 发送邮件到 miles@rtstu.com,主题为「软件认证申请」
  3. 等待热土工作室审核(通常1-3个工作日)
  4. 审核通过后,您将收到包含软件Token的邮件
注意: 软件认证申请需要确保您的软件符合热土用户系统的安全规范,不包含恶意代码或行为。

示例代码

以下是使用第三方API的示例代码:

验证软件Token

const axios = require('axios');

async function verifySoftwareToken(token) {
    try {
        const response = await axios.post('https://appapi.rtstudio.top/verify-software-token', {
            token: token
        });
        return response.data;
    } catch (error) {
        console.error('验证失败:', error);
        return { success: false, message: '验证失败' };
    }
}

// 使用示例
verifySoftwareToken('your_software_token')
    .then(result => {
        if (result.success) {
            console.log('软件验证成功:', result.data);
        } else {
            console.log('软件验证失败:', result.message);
        }
    });

验证用户授权Token

const axios = require('axios');

async function verifyAccessToken(token) {
    try {
        const response = await axios.post('https://appapi.rtstudio.top/verify-access-token', {
            token: token
        });
        return response.data;
    } catch (error) {
        console.error('验证失败:', error);
        return { success: false, message: '验证失败' };
    }
}

// 使用示例
verifyAccessToken('user_access_token')
    .then(result => {
        if (result.success) {
            console.log('Token验证成功:', result.data);
        } else {
            console.log('Token验证失败:', result.message);
        }
    });

获取用户信息

const axios = require('axios');

async function getUserByToken(token) {
    try {
        const response = await axios.post('https://appapi.rtstudio.top/get-user-by-token', {
            token: token
        });
        return response.data;
    } catch (error) {
        console.error('获取失败:', error);
        return { success: false, message: '获取失败' };
    }
}

// 使用示例
getUserByToken('user_access_token')
    .then(result => {
        if (result.success) {
            console.log('用户信息:', result.data);
        } else {
            console.log('获取失败:', result.message);
        }
    });

创建数据段

const axios = require('axios');

async function createDataSegment(email, token, name, content) {
    try {
        const response = await axios.post('https://appapi.rtstudio.top/data-segments', {
            email: email,
            token: token,
            name: name,
            content: content
        });
        return response.data;
    } catch (error) {
        console.error('创建数据段失败:', error);
        return { success: false, message: '创建失败' };
    }
}

// 使用示例
createDataSegment('user@example.com', 'user_access_token', 'user_settings', JSON.stringify({ theme: 'dark', language: 'zh-CN' }))
    .then(result => {
        if (result.success) {
            console.log('数据段创建成功:', result.data);
        } else {
            console.log('创建失败:', result.message);
        }
    });

修改数据段

const axios = require('axios');

async function updateDataSegment(email, token, name, content) {
    try {
        const response = await axios.put('https://appapi.rtstudio.top/data-segments', {
            email: email,
            token: token,
            name: name,
            content: content
        });
        return response.data;
    } catch (error) {
        console.error('修改数据段失败:', error);
        return { success: false, message: '修改失败' };
    }
}

// 使用示例
updateDataSegment('user@example.com', 'user_access_token', 'user_settings', JSON.stringify({ theme: 'light', language: 'zh-CN' }))
    .then(result => {
        if (result.success) {
            console.log('数据段更新成功:', result.data);
        } else {
            console.log('更新失败:', result.message);
        }
    });

删除数据段

const axios = require('axios');

async function deleteDataSegment(email, token, name) {
    try {
        const response = await axios.delete('https://appapi.rtstudio.top/data-segments', {
            data: {
                email: email,
                token: token,
                name: name
            }
        });
        return response.data;
    } catch (error) {
        console.error('删除数据段失败:', error);
        return { success: false, message: '删除失败' };
    }
}

// 使用示例
deleteDataSegment('user@example.com', 'user_access_token', 'user_settings')
    .then(result => {
        if (result.success) {
            console.log('数据段删除成功');
        } else {
            console.log('删除失败:', result.message);
        }
    });

读取数据段

const axios = require('axios');

async function readDataSegment(email, token, name) {
    try {
        const response = await axios.post('https://appapi.rtstudio.top/data-segments/read', {
            email: email,
            token: token,
            name: name
        });
        return response.data;
    } catch (error) {
        console.error('读取数据段失败:', error);
        return { success: false, message: '读取失败' };
    }
}

// 使用示例
readDataSegment('user@example.com', 'user_access_token', 'user_settings')
    .then(result => {
        if (result.success) {
            console.log('数据段读取成功:', result.data);
            // 解析JSON内容
            const content = JSON.parse(result.data.content);
            console.log('解析后的数据:', content);
        } else {
            console.log('读取失败:', result.message);
        }
    });

常见问题

Q: 软件Token和用户授权Token有什么区别?

A: 软件Token是用于标识软件身份的令牌,由热土工作室颁发给已认证的软件;用户授权Token是用户登录后生成的令牌,用于访问用户信息。

Q: 如何安全地存储软件Token?

A: 软件Token应该安全存储在软件中,避免硬编码在源代码中,建议使用环境变量或加密存储。

Q: 用户授权Token的有效期是多久?

A: 用户授权Token的有效期为1年,过期后需要重新登录。

Q: 如何申请软件认证?

A: 请发送邮件到 miles@rtstu.com 申请软件认证,包含软件名称、开发者信息、功能描述等。

Q: 第三方API的速率限制是多少?

A: 目前第三方API没有速率限制,但建议合理使用,避免过度请求。

Q: 数据段是什么?有什么用途?

A: 数据段是用户存储在热土用户系统中的数据,软件可以通过API创建、修改和删除这些数据段。数据段可以用于存储用户的设置、偏好、游戏存档等信息。

Q: 数据段的大小限制是多少?

A: 目前数据段的内容大小限制为1MB,超过这个限制的请求会被拒绝。

Q: 数据段的最大数量是多少?

A: 目前一个已授权的Token下可以存最多500个数据段

Q: 数据段的访问权限如何控制?

A: 数据段的访问需要提供用户邮箱和有效的访问Token,确保只有授权的软件能够访问用户的数据。

Q: 如何安全地存储用户的敏感信息?

A: 数据段中不建议存储密码、银行卡号等敏感信息。如果需要存储敏感信息,建议在客户端进行加密后再存储。

Q: 数据段的访问权限如何控制?

A: 数据段的访问需要提供用户邮箱和有效的访问Token,确保只有授权的软件能够访问用户的数据。