如何使用NodeJS为Agora应用程序构建Token服务器


目前,视频聊天app中的安全性是一个热门话题。 随着远程工作和虚拟事件变得越来越多,人们对安全性的需求也随之增加。

在Agora平台内,有一层安保是以token认证形式出现的。 而token是使用一组给定输入而生成的动态密钥。 Agora平台使用tokens对用户进行身份验证。

Agora为其RTC和RTM SDK提供token鉴权。 本指南将说明如何使用Express和NodeJS构建简单的微服务以生成Agora RTC token。因为遵循相似的运行模式,所以该示例也适用于RTM。

要求

  • 掌握与JavaScript ES6, NodeJS,和NPM相关的基础知识。

  • 至少要了解Express网络服务器功能

  • 一个Agora开发者账号(详见 声网注册指南

新建项目

在终端中,我们将运行npm init来设置项目。 接下来会出现创建项目提示。 我使用了默认设置,但是你也可以自定义这部分。

现在项目已经创建完成,我们可以使用以下命令添加NPM依赖项( express and agora-access-token )

npm install express
npm install agora-access-token

构建Express服务器

现在项目已经设置完毕,你可以在喜欢的代码编辑器中打开文件夹并查看package.json,你会注意到入口文件是index.js,但是该文件在我们的项目中不存在,因此我们必须创建一个新文件并将其命名为index.js。

在index.js文件中,我们将从模块引用开始。 从express中,我们将需要express对象,从agora-access-token中,我们将利用ES6的解构赋值来提取对RtcTokenBuilder和RtcRole对象的引用。

const express = require(‘express’);
const {RtcTokenBuilder, RtcRole} = require(‘agora-access-token’);

我们来为即将用于侦听请求的PORT号定义常量,我喜欢用8080。我们还将为Agora AppIDAppCertificate定义常量,我喜欢用环境变量,所以这些值在代码中并不显示,但你可以将这些值设置为包含各自Agora键的字符串

const PORT = 8080;const APP_ID = process.env.APP_ID;
const APP_CERTIFICATE = process.env.APP_CERTIFICATE;

接下来,,我们会定义app常量,这会使我们的Express对象实例化并允许我们建立自己的服务器。

const app = express();

在为Express服务器设置GET终端之前,我们需要定义访问端点时调用的函数。 第一个函数(nocache)将应用于响应头,这将强制浏览器不能缓存响应,因此我们要确保始终获得最新的token。 你会注意到我们在最后调用了next()方法,因为该函数是该系列中第一个中间件函数。因此我们需要调用next()让Express继续执行该系列中下一个中间件函数。

const nocache = (req, resp, next) => {
resp.header(‘Cache-Control’, ‘private, no-cache, no-store, must-revalidate’);
resp.header(‘Expires’, ‘-1’);
resp.header(‘Pragma’, ‘no-cache’);
next();
};

第二个函数(generateAccessToken)将处理请求并返回JSON响应。 现在,我们将定义函数,并在完成Express服务器的设置后添加主体。 这是该系列中的最后一个函数,因此我们不需要next参数/函数。

const generateAccessToken = (req, resp) => { };

接下来我们要定义GET终端,传入nochachegenerateAccessToken函数中。

app.get(’/access_token’, nocache, generateAccessToken);

创建Express服务器的最后一步,我们将实现.listen()方法,在服务器准备就绪并侦听给定端口后传入PORT并回调。

app.listen(PORT, () => {
console.log(Listening on port: ${PORT});
});

生成Agora Token

现在我们已经完成了Express服务器的设置,准备将功能添加到generateAccessToken函数中。 我们将从设置响应头开始,以确保不会遇到任何CORS问题。

获取查询参数

接下来,我们将检查channelName查询参数。 这是必要参数,因此,如果未定义channelName,我们则需要返回带有500响应码的错误和带有错误参数的JSON对象的地方。

const channelName = req.query.channelName;if (!hannelName) { return resp.status(500).json({ ‘error’: ‘channel is required’ }); }

接下来的几个参数( uid , role , expirationTime)不是必要的,所以我们只需根据需要将其指认为默认值就好了。

对于uid,我们将默认值设置为0,这使得我们可以生成 “通配符” ,其可以用任何uid加入指定频道。 这仅适用于安全性较低的情况下(或在开发过程中),所有用户都可以共享一个token。

一个低安全性的例子是直播,任何人都可以加入其中并以观众身份观看。

对于频道角色,我们将每个用户默认为观众,并且仅检查请求是否传达到主播那里,在其他方面的值都可以忽略。

请注意:只有默认的情况下,Agora平台才能执行加入频道的特权,要启用其他特权,您需要通过 Agora 支持 进行开通。

对于有效时间,我们将默认设置为3600秒,这使用户在权限到期之前有一个小时的时间加入频道。 关于截止时间要注意一件事,是token的权限时效必须是一个整数,例如从1970年1月1日开始。我们将使用当前时间,并添加时效。

// get uid
let uid = req.query.uid;
if(!uid uid == ‘’) {
uid = 0;
}
// get role
let role = RtcRole.SUBSCRIBER;
if (req.query.role == ‘publisher’) {
role = RtcRole.PUBLISHER;
}
// get the expire time
let expireTime = req.query.expireTime;
if (!expireTime expireTime == ‘’) {
expireTime = 3600;
} else {
expireTime = parseInt(expireTime, 10);
}
// calculate privilege expire time
const currentTime = Math.floor(Date.now() / 1000);
const privilegeExpireTime = currentTime + expireTime;

构建Token

现在,我们已经具备了构建token的所有条件,现在可以使用RtcTokenBuilder对象的buildTokenWithUid生成token了。

const token = RtcTokenBuilder.buildTokenWithUid(APP_ID, APP_CERTIFICATE, channelName, uid, role, privilegeExpireTime);

返回响应

生成token的最后一步是返回包含token的JSON响应。

return resp.json({ ‘token’: token });

测Token服务器

让我们回到package.json并在“ 脚本 ”对象中添加“ 开始 ”命令。 开始命令将执行“ node index.js ”命令,以便我们可以运行服务器实例。

“scripts”: { “test”: “echo “Error: no test specified” && exit 1”, “start”: “node index.js” },

启动服务器

让我们回到命令提示符窗口并使用新命令:

npm start

服务器实例侦听后,我们将在终端窗口中看到“正在侦听端口:8080”。

测试端点

现在我们的服务器实例已经处于运行状态,接下里我们要打开网络浏览器进行测试。 对于这些测试,我们将尝试一些省略各种查询参数的少量变体。

我们将从省略所有查询参数开始:

localhost:8080/access_token

这将显示:

{“error”:“channel is required”}

接下来,我们将通过“ test”作为channelName:

localhost:8080/access_token?channelName=test

这将可以输出任何用户都能使用的token。

{“token”:“0062ec0d84c41c4442d88ba6f5a2beb828bIAD9qg4N4hd04MvaY6A72m4BjYmO/7+xnRMinaI0ncLzkAx+f9gAAAAAEACS0zcn9gASXwEAAQCGvRBf”}

我们可以继续对其余查询参数进行测试,然后会得到与上述情况类似的响应。

localhost:8080/access_token?channelName=test&role=subscriberlocalhost:8080/access_token?channelName=test&role=subscriber&uid=1234localhost:8080/access_token?channelName=test&role=subscriber&uid=1234&expireTime=6400

完成啦!

这样就可以完成任务啦! 如果你的编码没跟上或想看成品,我已将所有代码上传到了GitHub。

感谢你抽出宝贵的时间阅读我的教程,如有任何疑问,请发表评论。 如发现有任何改进的空间,欢迎提交你的Pull Request!

作者 Hermes Frangoudis
原文链接](https://www.agora.io/en/blog/how-to-build-a-token-server-for-agora-applications-using-nodejs/)

推荐阅读
作者信息
AgoraTechnicalTeam
TA 暂未填写个人简介
文章
153
相关专栏
SDK 教程
55 文章
本专栏仅用于分享音视频相关的技术文章,与其他开发者和 Agora 研发团队交流、分享行业前沿技术、资讯。发帖前,请参考「社区发帖指南」,方便您更好的展示所发表的文章和内容。