视频聊天应用程序的安全性是很重要的。在Agora平台中,有一层安全性保护是以Token认证的形式出现的。本指南介绍了如何使用Java和Jersey来构建简单的微服务以生成Agora RTC令牌。
要求
- Apache Tomcat、IntelliJ IDEA IDE、Jersey框架和Docker。
- 对REST框架工作原理有基本了解。
- 理解Java类。
- Agora开发人员帐户。
主要事项:
- 建立一个Jersey项目。
- 创建一个Hello World API。
- 生成Agora令牌。
- 生成Dockerize应用程序并将其部署在Ubuntu VM上。
创建项目
Archetype: Archetype是一个Maven项目模板工具包。
Artifact: 是一个文件,通常是一个被部署到 Maven 资源库的JAR文件。创建完的 Maven 能产生一个或多个 artifacts ,诸如编译JAR文件和JAR源文件。
jersey-quickstart-webapp 提供了一个基本的项目模板,对于初学者很有用并且足够强大。
打开 IntelliJ IDE ,然后单击“开始新项目”,我们将用 Maven 来创建新项目。单击 Archetype中的 创建,然后添加具有以下配置的 Archetype 。
Group Id: org.glassfish.jersey.archetypes
Artifact Id: jersey-quickstart-webapp
Version: 2.31
项目的最终配置如下所示:
项目创建完成后,我们将添加Tomcat服务器。如果还没有安装,则可以从Tomcat官方网站获取Tomcat 。安装完Tomcat后,你可以单击创建图标旁边的 添加配置 。
从 模板中 选择本地Tomcat服务器。最终配置如下所示:
完成应用配置并关闭配置窗口。你已经完成Jersey项目的创建并配置了Tomcat服务器。
Hello World API
在这个部分,你将会使用JSON和XML的输入、输出创建Hello World API。
导航到 pom.xml (包含所有Maven依赖项),取消注释JSON依赖项,然后添加JAVAX依赖项。你的依赖项应如下所示:
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-binding</artifactId>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.6</version>
</dependency>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
</dependency>
</dependencies>
编辑 src / main / webapp / index.JSP 并将以下代码添加到文件中:
<html>
<body>
<h2>Agora Token Server</h2>
<p><a href="webapi/myresource">Agora resource</a>
<p>Visit <a href="https://agora.io/">Agora.io website</a>
for more information on Agora!
</body>
</html>
现在编译项目。之后,IntelliJ会为你打开浏览器。默认情况下, index.JSP 文件都显示在浏览器中。浏览器应显示以下内容:
单击 jersey资源,它将重新引导你到新的页面:
注意 URL 。默认情况下, ServerletMapping 将所有内容映射到 */ webapi / 。你要 将其改为/ *。
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>Agora Token Server</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.sandeep.agoratoken</param-value> <!-- Remember to replace this -->
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Agora Token Server</servlet-name>
<url-pattern>/webapi/*</url-pattern>
</servlet-mapping>
</web-app>
重新启动服务器。 webapi 已被删除。
怎么做到让它出现在网站上?
转到MyResource Java类。看起来就像这样:
在这里,我们添加了 路径注释(@ PATH), 用于为MyResource类传入的HTTP请求定义一个URI匹配模式。
由于 Path annotation ,我们在URL中获得了“ myresource ” (即@ PATH(“ myresource”) )。我们为 getIt() 方法定义了 @ GET (第12行) ,它指定它将使用 GET HTTP方法.@ Produces annotation (第13行) 定义返回响应格式。
现在,添加 Agora 到项目中。
继续访问声网GitHub仓库,克隆整个仓库,然后复制并粘贴Media和RTM文件夹。文件结构应如下所示:
注意: 找到每个文件更正软件包名称以避免发生错误。就我而言,它应该是 com.sandeep.agoratoken 而不是 io.agora。 通常情况下,IntelliJ帮你执行此操作。
单击右键将java文件命名为Agora、AgoraRepository和AgoraRTMRepository,然后删除MyResource文件后,3个新的Java类就创建完成了。
将以下代码粘贴到你的AgoraRepository中:
package com.sandeep.agoratoken; //make sure you change this
public class AgoraRepository {
static String appId = "APP_ID";
static String appCertificate ="APP_CERIFICATE";
private String channelName;
private int uid = 0; // By default 0
private int expirationTimeInSeconds = 3600; // By default 3600
private int role = 2; // By default subscriber
}
将以下代码粘贴到您的AgoraRTMRepository中
package com.sandeep.agoratoken;
public class AgoraRTMRepository {
private static String appId = "APP_ID";
private static String appCertificate = "APP_CERT";
private String userId;
private int expireTimestamp = 0;
}
现在,你需要获取器和设置器。
转到AgoraRepository类,然后根据操作系统输入命令:
* Ctrl + N for Linux and Windows users
* Cmd + N for Mac users
上述命令的替换
你的文件应如下所示:
package com.sandeep.agoratoken;
public class AgoraRepository {
static String appId = "APP_ID"; //replace app id
static String appCertificate = "APP_CERT"; //replace app cert
private String channelName;
private int uid = 0;
private int expirationTimeInSeconds = 3600;
private int role = 2; // By default subscriber
public static String getAppId() {
return appId;
}
public static void setAppId(String appId) {
AgoraRepository.appId = appId;
}
public static String getAppCertificate() {
return appCertificate;
}
public static void setAppCertificate(String appCertificate) {
AgoraRepository.appCertificate = appCertificate;
}
public String getChannelName() {
return channelName;
}
public void setChannelName(String channelName) {
this.channelName = channelName;
}
public int getUid() {
return uid;
}
public void setUid(int uid) {
this.uid = uid;
}
public int getExpirationTimeInSeconds() {
return expirationTimeInSeconds;
}
public void setExpirationTimeInSeconds(int expirationTimeInSeconds) {
this.expirationTimeInSeconds = expirationTimeInSeconds;
}
public int getRole() {
return role;
}
public void setRole(int role) {
this.role = role;
}
}
在AgoraRTMRepository中重复此步骤。你的文件现在应如下所示:
package com.sandeep.agoratoken;
public class AgoraRTMRepository {
private static String appId = "APP_ID";
private static String appCertificate = "APP_CERT";
private String userId = "USER_ID";
private int expireTimestamp = 0;
public static String getAppId() {
return appId;
}
public static String getAppCertificate() {
return appCertificate;
}
public static void setAppCertificate(String appCertificate) {
AgoraRTMRepository.appCertificate = appCertificate;
}
public String getUserId() {
return userId;
}
public int getExpireTimestamp() {
return expireTimestamp;
}
public static void setAppId(String appId) {
AgoraRTMRepository.appId = appId;
}
}
你会看到类似这样的内容,单击“获取器和设置器”,然后选择所有内容。这样Agora Token Server差不多就完成了 。
导入内容并定义 Token Server RTC POST Request:
package com.sandeep.agoratoken;
import com.sandeep.agoratoken.media.RtcTokenBuilder;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.json.simple.JSONObject;
@Path("api")
public class Agora{
@POST
@Path("rtc")
@Produces(MediaType.APPLICATION_JSON)
public Object getRTCToken(AgoraRepository resource) {
}
}
初始化所有参数:
package com.sandeep.agoratoken;
import com.sandeep.agoratoken.media.RtcTokenBuilder;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.json.simple.JSONObject;
@Path("api")
public class Agora{
@POST
@Path("rtc")
@Produces(MediaType.APPLICATION_JSON)
public Object getRTCToken(AgoraRepository resource) {
RtcTokenBuilder token = new RtcTokenBuilder();
String channelName = resource.getChannelName();
int expireTime = resource.getExpirationTimeInSeconds();
RtcTokenBuilder.Role role = RtcTokenBuilder.Role.Role_Subscriber;
int uid = resource.getUid();
}
}
创建Token之前先检查一下,确保万无一失:
package com.sandeep.agoratoken;
import com.sandeep.agoratoken.media.RtcTokenBuilder;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.json.simple.JSONObject;
@Path("api")
public class Agora{
@POST
@Path("rtc")
@Produces(MediaType.APPLICATION_JSON)
public Object getRTCToken(AgoraRepository resource) {
RtcTokenBuilder token = new RtcTokenBuilder();
String channelName = resource.getChannelName();
int expireTime = resource.getExpirationTimeInSeconds();
RtcTokenBuilder.Role role = RtcTokenBuilder.Role.Role_Subscriber;
int uid = resource.getUid();
// check for null channelName
if (channelName==null){
JSONObject error=new JSONObject();
error.put("error","Channel ID cannot be blank");
return Response.status(Response.Status.BAD_REQUEST).entity(error).build();
}
if(expireTime==0){
expireTime = 3600;
}
if(resource.getRole()==1){
role = RtcTokenBuilder.Role.Role_Publisher;
}else if(resource.getRole()==0){
role = RtcTokenBuilder.Role.Role_Attendee;
}
}
}
创建一个时间戳并生成令牌:
package com.sandeep.agoratoken;
import com.sandeep.agoratoken.media.RtcTokenBuilder;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.json.simple.JSONObject;
@Path("api")
public class Agora{
@POST
@Path("rtc")
@Produces(MediaType.APPLICATION_JSON)
public Object getRTCToken(AgoraRepository resource) {
RtcTokenBuilder token = new RtcTokenBuilder();
String channelName = resource.getChannelName();
int expireTime = resource.getExpirationTimeInSeconds();
RtcTokenBuilder.Role role = RtcTokenBuilder.Role.Role_Subscriber;
int uid = resource.getUid();
// check for null channelName
if (channelName==null){
JSONObject error=new JSONObject();
error.put("error","Channel ID cannot be blank");
return Response.status(Response.Status.BAD_REQUEST).entity(error).build();
}
if(expireTime==0){
expireTime = 3600;
}
if(resource.getRole()==1){
role = RtcTokenBuilder.Role.Role_Publisher;
}else if(resource.getRole()==0){
role = RtcTokenBuilder.Role.Role_Attendee;
}
int timestamp = (int)(System.currentTimeMillis() / 1000 + expireTime);
String result = token.buildTokenWithUid(resource.appId, resource.appCertificate,
channelName, uid, role, timestamp);
System.out.print(result);
JSONObject jsondict = new JSONObject();
jsondict.put("message",result);
return jsondict;
}
}
Agora Java RTC token server.创建完成! 现在就可以启动了 。
将以下代码添加到你的Agora类中:
@POST
@Path("rtm")
@Produces(MediaType.APPLICATION_JSON)
public Object getRTMToken(AgoraRTMRepository resource) throws Exception {
String userId = resource.getUserId();
if (userId==null){
JSONObject error=new JSONObject();
error.put("error","User ID cannot be blank");
return Response.status(Response.Status.BAD_REQUEST).entity(error).build();
}
RtmTokenBuilder token = new RtmTokenBuilder();
String result = token.buildToken(resource.getAppId(), resource.getAppCertificate(), userId, Role.Rtm_User, resource.getExpireTimestamp());
System.out.println(result);
JSONObject jsondict = new JSONObject();
jsondict.put("message",result);
return jsondict;
}
最终代码应如下所示:
package com.sandeep.agoratoken;
import com.sandeep.agoratoken.media.RtcTokenBuilder;
import com.sandeep.agoratoken.rtm.RtmTokenBuilder;
import com.sandeep.agoratoken.rtm.RtmTokenBuilder.Role;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.json.simple.JSONObject;
@Path("api")
public class Agora{
@POST
@Path("rtc")
@Produces(MediaType.APPLICATION_JSON)
public Object getRTCToken(AgoraRepository resource) {
RtcTokenBuilder token = new RtcTokenBuilder();
String channelName = resource.getChannelName();
int expireTime = resource.getExpirationTimeInSeconds();
RtcTokenBuilder.Role role = RtcTokenBuilder.Role.Role_Subscriber;
int uid = resource.getUid();
// check for null channelName
if (channelName==null){
JSONObject error=new JSONObject();
error.put("error","Channel ID cannot be blank");
return Response.status(Response.Status.BAD_REQUEST).entity(error).build();
}
if(expireTime==0){
expireTime = 3600;
}
if(resource.getRole()==1){
role = RtcTokenBuilder.Role.Role_Publisher;
}else if(resource.getRole()==0){
role = RtcTokenBuilder.Role.Role_Attendee;
}
int timestamp = (int)(System.currentTimeMillis() / 1000 + expireTime);
String result = token.buildTokenWithUid(resource.appId, resource.appCertificate,
channelName, uid, role, timestamp);
System.out.print(result);
JSONObject jsondict = new JSONObject();
jsondict.put("message",result);
return jsondict;
}
@POST
@Path("rtm")
@Produces(MediaType.APPLICATION_JSON)
public Object getRTMToken(AgoraRTMRepository resource) throws Exception {
String userId = resource.getUserId();
if (userId==null){
JSONObject error=new JSONObject();
error.put("error","User ID cannot be blank");
return Response.status(Response.Status.BAD_REQUEST).entity(error).build();
}
RtmTokenBuilder token = new RtmTokenBuilder();
String result = token.buildToken(resource.getAppId(), resource.getAppCertificate(), userId, Role.Rtm_User, resource.getExpireTimestamp());
System.out.println(result);
JSONObject jsondict = new JSONObject();
jsondict.put("message",result);
return jsondict;
}
}
你以为这就大功告成了吗?不,我们还需要部署。
部署方式
首先,你需要创建一个 WAR文件。 从右侧切换栏打开Maven,然后单击Maven图标执行命令:
现在运行 mvn clean package
一两分钟就会生成一个WAR文件,你可以看到WAR文件的位置。
在你的存储库中创建一个Dockerfile,并将你的代码推送到GitHub。
FROM tomcat:9.0.37
MAINTAINER SaiSandeep
COPY target/agoratoken.war /usr/local/tomcat/webapps/ROOT.war
EXPOSE 8080
CMD ["catalina.sh", "run"]
创建一个Ubuntu VM。
运行以下命令在Linux上安装Docker:
sudo apt-get update
sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
Mac和Windows用户可以从此Docker官方网站中获取可执行文件。
运行此命令以检查是否已安装Docker-> docker -v
将你的仓库克隆到VM。并运行以下命令:
nano src/main/java/com/sandeep/agoratoken/MyResourceRepository.java
填写你的APP_ID和APP_CERT。你就可以从Agora.io控制台获取APP_ID和APP_CERT。
要构建Docker映像,请运行以下命令:
docker build -t agoratoken ./
OK,运行!
docker run -p 80:8080 agoratoken
检查API。
更多资源
有关Agora.io应用程序令牌的更多信息,请参阅《设置身份验证指南》和《Agora高级指南:如何构建令牌(Go)》 。
Github库:AgoraToken参考代码
原文作者 Agora Superstar
原文链接https://www.agora.io/en/blog/building-an-agora-token-server-using-java/
使用 `RtcTokenBuilder2` API 的话是需要 jdk 版本 9 以上吗?