You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter集成Agora时,云函数生成的RTC Token始终提示无效

问题排查与修复方案

我用以下云函数代码为Flutter应用生成Agora视频通话的RTC Token,Agora控制台生成的临时Token能正常使用,但云函数生成的Token却报错,已经确认AppID和AppCertificate是正确的。

import pkg from 'agora-access-token';
const { RtcTokenBuilder, RtcRole } = pkg;

export default async ({ req, res, log, error }) => {
   if (req.method === 'POST') {
   let requestBody;
if (typeof req.body === 'string') {
  requestBody = JSON.parse(req.body);
} else {  
  requestBody = req.body; 
}
const { channelName, uid } = requestBody;
const appId = process.env.APP_ID;
const appCertificate = process.env.APP_CERTIFICATE;
const role = RtcRole.PUBLISHER;
log('Request body:', requestBody);
log('Channel Name:', channelName);
log('UID:', uid);
log('App ID:', appId);
log('App Certificate:', appCertificate);

const expirationTimeInSeconds = 3600;
const currentTimestamp = Math.floor(Date.now() / 1000);
const privilegeExpiredTs = Math.floor(currentTimestamp + expirationTimeInSeconds);

const token = RtcTokenBuilder.buildTokenWithUid(
  appId, 
  appCertificate, 
  channelName, 
  uid,
  role, 
  privilegeExpiredTs
);

log('Generated Token:', token);

return res.json({ token, uid: uid.toString() });
} else {
res.status(405).json({ message: 'Method not allowed' });
}
}

核心排查点与修复

1. UID类型不匹配

RtcTokenBuilder.buildTokenWithUid要求uid是整数类型,如果前端传入的uid是字符串格式(比如"12345"),直接传入会导致Token生成逻辑错误。

修复:
提取uid后转为整数,并处理非法值:

const { channelName, uid: rawUid } = requestBody;
const uid = parseInt(rawUid, 10);
const finalUid = isNaN(uid) ? 0 : uid; // 0表示Agora随机分配UID

2. 频道名大小写/格式问题

Agora频道名大小写敏感,且仅允许a-z、A-Z、0-9、-_!#$%&()+-<>.?@[]^_{}~这些字符。如果请求传入的频道名包含非法字符,或与前端连接时的频道名大小写不一致,会导致Token验证失败。

修复:
生成Token前标准化频道名:

const normalizedChannel = channelName.trim().toLowerCase();

3. 请求体解析异常

如果请求体格式不符合JSON规范,JSON.parse会抛出错误,导致后续逻辑中断。

修复:
添加解析异常捕获:

let requestBody;
try {
  requestBody = typeof req.body === 'string' ? JSON.parse(req.body) : req.body;
} catch (err) {
  error('请求体解析失败:', err);
  return res.status(400).json({ message: '无效的请求体格式' });
}

4. 环境变量与参数校验

虽然你确认过AppID和证书正确,但仍需确保云函数能完整读取环境变量,且请求参数不缺失。

修复:
添加参数与环境变量校验:

if (!channelName || rawUid === undefined) {
  return res.status(400).json({ message: '缺少channelName或uid参数' });
}
if (!appId || !appCertificate) {
  error('环境变量APP_ID或APP_CERTIFICATE未配置');
  return res.status(500).json({ message: '服务器配置错误' });
}

修复后的完整代码

import pkg from 'agora-access-token';
const { RtcTokenBuilder, RtcRole } = pkg;

export default async ({ req, res, log, error }) => {
  if (req.method === 'POST') {
    let requestBody;
    try {
      requestBody = typeof req.body === 'string' ? JSON.parse(req.body) : req.body;
    } catch (parseErr) {
      error('请求体解析错误:', parseErr);
      return res.status(400).json({ message: '无效的请求体格式' });
    }

    const { channelName, uid: rawUid } = requestBody;
    if (!channelName || rawUid === undefined) {
      return res.status(400).json({ message: '缺少channelName或uid参数' });
    }

    const appId = process.env.APP_ID;
    const appCertificate = process.env.APP_CERTIFICATE;
    if (!appId || !appCertificate) {
      error('环境变量APP_ID或APP_CERTIFICATE未配置');
      return res.status(500).json({ message: '服务器配置错误' });
    }

    const role = RtcRole.PUBLISHER;
    const uid = parseInt(rawUid, 10);
    const finalUid = isNaN(uid) ? 0 : uid;
    const normalizedChannel = channelName.trim().toLowerCase();

    const expirationTimeInSeconds = 3600;
    const currentTimestamp = Math.floor(Date.now() / 1000);
    const privilegeExpiredTs = currentTimestamp + expirationTimeInSeconds;

    const token = RtcTokenBuilder.buildTokenWithUid(
      appId, 
      appCertificate, 
      normalizedChannel, 
      finalUid,
      role, 
      privilegeExpiredTs
    );

    log('生成Token成功:频道=', normalizedChannel, 'UID=', finalUid);
    return res.json({ token, uid: finalUid.toString() });
  } else {
    res.status(405).json({ message: '不允许的请求方法' });
  }
}

内容的提问来源于stack exchange,提问作者MaryKor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 04:46:19