第三章 用户管理API:获取用户信息、粉丝列表、关注列表与授权数据管理
用户管理这块,说实话是抖音开放平台里最基础也最核心的部分。我刚开始对接的时候,以为就是简单调几个接口拿数据,结果踩了不少坑。今天咱们就把这块彻底捋清楚。
3.1 获取用户信息
这个接口说白了就是拿当前授权用户的公开资料。你想想看,头像、昵称、性别、地区这些,都是做个性化推荐的基础。
接口地址:GET https://open.douyin.com/oauth/userinfo/
请求参数:access_token(必填)
我个人习惯在拿到 access_token 后,第一时间就去拉用户信息。为什么?因为很多业务逻辑依赖用户的基本属性,早拿早安心。
// 伪代码示例
async function getUserInfo(accessToken) {
const url = `https://open.douyin.com/oauth/userinfo/?access_token=${accessToken}`;
const response = await fetch(url);
const data = await response.json();
if (data.message === 'success') {
return {
openId: data.data.open_id,
nickname: data.data.nickname,
avatar: data.data.avatar,
gender: data.data.gender, // 0未知 1男性 2女性
city: data.data.city,
province: data.data.province
};
}
throw new Error(`获取用户信息失败: ${data.message}`);
}
小提示:我在项目中遇到过用户信息里的城市字段为空的情况。后来发现,有些用户没授权位置信息。所以你的代码里一定要做空值处理,别直接拿 city 去拼接地址。
3.2 获取用户粉丝列表
粉丝列表这个接口,嗯,这里要注意。它返回的不是全部粉丝,而是有数量限制的。默认一次最多返回 50 条,你需要用 cursor 做分页。
接口地址:GET https://open.douyin.com/fans/list/
请求参数:access_token, open_id, cursor(可选), count(可选,默认10,最大50)
我曾经在做一个粉丝分析工具时,需要拉取某个大V的全部粉丝。一开始没注意分页逻辑,结果只拿到了前50个。后来才发现 cursor 的用法——每次返回的 JSON 里会带一个 cursor 字段,你把它传给下一次请求就行。
// 分页拉取粉丝列表
async function getAllFans(accessToken, openId) {
let cursor = 0;
let hasMore = true;
const allFans = [];
while (hasMore) {
const url = `https://open.douyin.com/fans/list/?access_token=${accessToken}&open_id=${openId}&cursor=${cursor}&count=50`;
const response = await fetch(url);
const result = await response.json();
if (result.data.list) {
allFans.push(...result.data.list);
}
cursor = result.data.cursor;
hasMore = result.data.has_more; // 1表示还有更多
}
return allFans;
}
注意:粉丝列表接口有频率限制。我记得文档里写的是单个用户每天最多调用 1000 次。如果你要批量拉取大量粉丝,建议加个延时,比如每次请求间隔 200ms。不然很容易被限流。
3.3 获取用户关注列表
关注列表和粉丝列表的接口结构几乎一样。说白了就是一个是「谁关注了我」,一个是「我关注了谁」。但有个细节——关注列表里会多一个字段叫 is_follow,表示你是否也关注了对方。
接口地址:GET https://open.douyin.com/following/list/
请求参数:同粉丝列表
你想想看,这个字段有什么用?我做过一个互关检测功能,就是靠这个字段来判断「双向关注」的关系。代码写起来很简单:
// 检测是否互关
function checkMutualFollow(followingList) {
return followingList.filter(user => user.is_follow === true);
}
不过要注意,is_follow 这个字段只在关注列表里出现。粉丝列表里没有这个字段。我当时想偷懒,想从粉丝列表里直接判断互关,结果发现不行。最后还是老老实实调了两个接口。
3.4 用户授权数据管理
这块其实是最容易被忽略的。很多开发者拿到 access_token 就以为万事大吉了。但 token 是会过期的!
access_token 有效期:默认 7 天
refresh_token 有效期:默认 30 天
我建议你做一个 token 管理模块,专门负责 token 的存储、刷新和过期处理。别把 token 硬编码在代码里,也别只存数据库不设过期时间。
// Token 管理示例
class TokenManager {
constructor() {
this.tokenStore = new Map(); // 生产环境建议用 Redis
}
async getValidToken(openId) {
const tokenData = this.tokenStore.get(openId);
if (!tokenData) {
throw new Error('未找到 token,需要重新授权');
}
// 检查是否过期(提前5分钟刷新)
if (Date.now() > tokenData.expiresAt - 5 * 60 * 1000) {
return await this.refreshToken(tokenData.refreshToken);
}
return tokenData.accessToken;
}
async refreshToken(refreshToken) {
// 调用刷新接口
const url = `https://open.douyin.com/oauth/refresh_token/?refresh_token=${refreshToken}`;
const response = await fetch(url);
const data = await response.json();
// 更新存储
this.tokenStore.set(data.data.open_id, {
accessToken: data.data.access_token,
refreshToken: data.data.refresh_token,
expiresAt: Date.now() + data.data.expires_in * 1000
});
return data.data.access_token;
}
}
避坑指南:我曾经犯过一个错误——在 token 过期后才去刷新。结果发现 refresh_token 也有使用次数限制。每个 refresh_token 只能用一次,刷新后会返回新的 refresh_token。如果你忘了更新,下次就没法刷新了。嗯,这个坑我替你们踩过了。
3.5 授权数据的安全存储
用户授权数据里包含 open_id、access_token、refresh_token 这些敏感信息。我个人习惯是:
- open_id 可以明文存储,因为它只是用户标识
- access_token 和 refresh_token 必须加密存储
- 数据库里加个字段记录 token 的过期时间,方便定时清理
- 不要在前端页面里暴露任何 token 信息
说白了,你把 token 泄露出去,就等于把用户的账号权限拱手让人了。这个责任可担不起。
我的经验:建议用 AES 加密存储 token,密钥单独放在配置中心或环境变量里。别写死在代码里。我之前见过有人把密钥直接写在 GitHub 上的,那画面太美我不敢看。
3.6 接口调用实战建议
最后总结一下我实际对接时的流程:
- 用户授权后,拿到 code,换取 access_token 和 refresh_token
- 立即调用用户信息接口,获取用户基本资料
- 将 token 和用户信息存入数据库(token 加密)
- 根据业务需求,按需调用粉丝列表或关注列表
- 每次调用前检查 token 是否过期,过期则自动刷新
- 做好异常处理,比如网络超时、接口限流等
这套流程我用了很久,基本没出过问题。你照着这个思路来,应该能少走不少弯路。
好了,用户管理 API 这块就讲到这里。下一章咱们聊聊视频管理,那个坑更多,到时候我好好给你们讲讲。