目前,视频聊天app中的安全性是一个热门话题。 随着远程工作和虚拟事件变得越来越多,人们对安全性的需求也随之增加。
在Agora平台内,有一层安保是以token认证形式出现的。 而token是使用一组给定输入而生成的动态密钥。 Agora平台使用tokens对用户进行身份验证。
Agora为其RTC和RTM SDK提供token安全。 本指南将说明如何使用Express和NodeJS构建简单的微服务以生成Agora RTC token。因为遵循相似的运行模式,所以该示例也适用于RTM。
要求
-
至少要了解Express网络服务器功能
-
一个Agora开发者账号(详见How To Get Started with 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 AppID和AppCertificate定义常量,我喜欢用环境变量,所以这些值在代码中并不显示,但你可以将这些值设置为包含各自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();
};
nocache.js hosted with by GitHub
第二个函数(generateAccessToken)将处理请求并返回JSON响应。 现在,我们将定义函数,并在完成Express服务器的设置后添加主体。 这是该系列中的最后一个函数,因此我们不需要next参数/函数。
const generateAccessToken = (req, resp) => { };
接下来我们要定义GET终端,传入nochache和generateAccessToken函数中。
app.get(’/access_token’, nocache, generateAccessToken);
创建Express服务器的最后一步,我们将实现.listen()方法,在服务器准备就绪并侦听给定端口后传入PORT并回调。
app.listen(PORT, () => {
console.log(Listening on port: ${PORT}
);
});
appListen.js hosted with by GitHub
生成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 Support .进行请求。
对于有效时间
,我们将默认设置为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;
getQueryParams.js hosted with by GitHub
构建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/)