GoLang을 사용하여 Agora 애플리케이션을 위한 토큰 서버 구축 방법
Agora 플랫폼에서 보안은 영패 인증 형식으로 나타납니다.모르는 사람에게 영패는 주어진 입력으로 생성된 동적 키를 사용합니다.Agora의 플랫폼은 영패를 사용하여 사용자를 인증합니다.
Agora는 RTC와 RTM SDK에 영패 보안을 제공합니다.이 안내서는 Golang과 Gin framework를 이용하여 간단한 마이크로서비스를 구축하여 Agora RTC와 RTM 영패를 생성하는 방법을 설명할 것이다.
선결 조건
프로젝트 설정
우선, 터미널을 열어 프로젝트에 새 폴더를 만들고 cd를 넣습니다.
mkdir agora-token-server
cd agora-token-server
프로젝트가 생성되었습니다. 프로젝트의 Go 모듈을 초기화합니다.go mod init agora-token-server
마지막으로 Gin과 Agora 의존 항목을 추가하려면 go get
을 사용합니다.go get github.com/gin-gonic/gin
go get github.com/AgoraIO-Community/go-tokenbuilder
Gin 웹 서버 구축
현재 항목이 설정되어 있습니다. 가장 좋아하는 코드 편집기에서 폴더를 열고
main.go
파일을 만듭니다.main.go
에서, 우리는 우선 우리의 가방을 설명하고 main
함수를 추가할 것이다.package main
func main() {
}
다음은 가져오기Gin framework로 Gin 응용 프로그램을 만들고 간단한 GET
단점을 설정하여 정청으로 설정하고 localhost
포트8080
에서 서비스할 것입니다.단순 노드에 대해 요청 컨텍스트를 가져오고 200
상태 헤더가 있는 JSON 응답을 반환하도록 설정합니다.package main
import (
"github.com/gin-gonic/gin"
)
func main() {
api := gin.Default()
api.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
})
api.Run(":8080") // listen and serve on localhost:8080
}
우리는 이미 우리의 서버를 테스트할 준비가 되어 있다.터미널 창으로 돌아가서 실행:go run main.go
끝점을 테스트하려면 웹 브라우저를 열고 다음을 액세스하십시오.
localhost:8080/ping
서버가 예상대로 응답하는 것을 볼 수 있습니다.{"message":"pong"}
엔드포인트 작업을 확인한 후 터미널 창으로 돌아가 키보드 명령ctrl c
을 사용하여 프로세스를 종료합니다.아고라 영패 생성
이제 Gin 서버 설정을 마쳤습니다. RTC와 RTM 토큰을 생성하는 기능을 추가할 예정입니다.
영패를 생성하기 전에
AppID
과AppCertificate
를 추가해야 합니다.우리는 appID
및 appCertificate
범위의 문자열로 성명할 것입니다.이 가이드에서는 환경 변수를 사용하여 프로젝트 자격 증명을 저장하므로 읽어들여야 합니다.global
에서 환경 변수를 검색하려면 main()
를 사용합니다.os.LookupEnv
환경 변수의 문자열과 해당 변수의 부울 값을 반환합니다.우리는 환경 설정이 정확한지 확인하기 위해 다음 반환 값을 사용할 것이다.만약 그렇다면, 우리는 각각 환경 변수 값을 전역 os.LookupEnv
과 appID
변수에 분배할 수 있다.package main
import (
"log"
"os"
"github.com/gin-gonic/gin"
)
var appID, appCertificate string
func main() {
appIDEnv, appIDExists := os.LookupEnv("APP_ID")
appCertEnv, appCertExists := os.LookupEnv("APP_CERTIFICATE")
if !appIDExists || !appCertExists {
log.Fatal("FATAL ERROR: ENV not properly configured, check APP_ID and APP_CERTIFICATE")
} else {
appID = appIDEnv
appCertificate = appCertEnv
}
api := gin.Default()
api.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
})
api.Run(":8080")
}
다음에 우리는 세 개의 단점을 추가할 것이다. 하나는 RTC 영패, 다른 하나는 RTM 영패, 그리고 하나는 두 개의 영패를 되돌려준다.RTC 영패는 문자열과 정수를 기반으로 하는 UID를 구분하기 위해 채널 이름, UID, 사용자 역할, 영패 유형이 필요합니다. 마지막은 만료 시간입니다.RTM 끝에는 UID 및 만료 시간만 필요합니다.이중 영패 단점은 RTC 영패 단점과 같은 구조를 받아들여야 한다.
api.GET("rtc/:channelName/:role/:tokentype/:uid/", getRtcToken)
api.GET("rtm/:uid/", getRtmToken)
api.GET("rte/:channelName/:role/:tokentype/:uid/", getBothTokens)
중복 코드의 수를 최소화하기 위해 세 함수AppCertificate
, getRtcToken
, getRtmToken
는 단독 함수(getBothTokens
/parseRtcParams
를 호출하여 각 단점에 전달되는 값을 검증하고 추출합니다.그리고 각 함수는 되돌아오는 값을 사용하여 영패를 생성하고 응답에서 JSON으로 되돌아온다parseRtmParams
.RTC 영패는 두 가지 유형의 UID(
body
/uint
를 사용하여 생성할 수 있으므로 함수(string
포장Agora RTC Token Builder함수generateRtcToken
/BuildTokenWithUserAccount
를 사용합니다.다음은 영패 서버의 기본 템플릿입니다.우리는 모든 함수를 두루 훑어보고 빈칸을 채울 것이다.
package main
import (
"log"
"os"
"github.com/AgoraIO-Community/go-tokenbuilder/rtctokenbuilder"
"github.com/gin-gonic/gin"
)
var appID, appCertificate string
func main() {
appIDEnv, appIDExists := os.LookupEnv("APP_ID")
appCertEnv, appCertExists := os.LookupEnv("APP_CERTIFICATE")
if !appIDExists || !appCertExists {
log.Fatal("FATAL ERROR: ENV not properly configured, check APP_ID and APP_CERTIFICATE")
} else {
appID = appIDEnv
appCertificate = appCertEnv
}
api := gin.Default()
api.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
})
api.GET("rtc/:channelName/:role/:tokenType/:uid/", getRtcToken)
api.GET("rtm/:uid/", getRtmToken)
api.GET("rte/:channelName/:role/:tokenType/:uid/", getBothTokens)
api.Run(":8080")
}
func getRtcToken(c *gin.Context) {
}
func getRtmToken(c *gin.Context) {
}
func getBothTokens(c *gin.Context) {
}
func parseRtcParams(c *gin.Context) (channelName, tokentype, uidStr string, role rtctokenbuilder.Role, expireTimestamp uint32, err error) {
}
func parseRtmParams(c *gin.Context) (uidStr string, expireTimestamp uint32, err error) {
}
func generateRtcToken(channelName, uidStr, tokentype string, role rtctokenbuilder.Role, expireTimestamp uint32) (rtcToken string, err error) {
}
RTC 영패 구축
우리는
BuildTokenWithUID
부터 시작할 것이다.이 함수 인용getRtcToken
, 호출gin.Context
을 사용하면 후자는 필요한 값을 추출합니다.그리고 되돌아오는 값 호출 parseRtcParams
을 사용하여 영패 문자열을 생성합니다.우리는 과정 중에 아무런 문제가 없도록 일부 오류 검사도 포함할 것이다.마지막으로, 우리는 응답을 구축할 것이다.func getRtcToken(c *gin.Context) {
log.Printf("rtc token\n")
// get param values
channelName, tokentype, uidStr, role, expireTimestamp, err := parseRtcParams(c)
if err != nil {
c.Error(err)
c.AbortWithStatusJSON(400, gin.H{
"message": "Error Generating RTC token: " + err.Error(),
"status": 400,
})
return
}
rtcToken, tokenErr := generateRtcToken(channelName, uidStr, tokentype, role, expireTimestamp)
if tokenErr != nil {
log.Println(tokenErr) // token failed to generate
c.Error(tokenErr)
errMsg := "Error Generating RTC token - " + tokenErr.Error()
c.AbortWithStatusJSON(400, gin.H{
"status": 400,
"error": errMsg,
})
} else {
log.Println("RTC Token generated")
c.JSON(200, gin.H{
"rtcToken": rtcToken,
})
}
}
다음은 우리 generateRtcToken
를 기입합시다.이 함수는 gin도 인용합니다.상하문, 우리는 그것을 사용하여 파라미터를 추출하고 되돌려 줄 것이다.parseRtcParams
또한 오류를 되돌려줍니다. 문제가 발생하면 오류 메시지를 되돌려줄 수 있습니다.
func parseRtcParams(c *gin.Context) (channelName, tokentype, uidStr string, role rtctokenbuilder.Role, expireTimestamp uint32, err error) {
// get param values
channelName = c.Param("channelName")
roleStr := c.Param("role")
tokentype = c.Param("tokentype")
uidStr = c.Param("uid")
expireTime := c.DefaultQuery("expiry", "3600")
if roleStr == "publisher" {
role = rtctokenbuilder.RolePublisher
} else {
role = rtctokenbuilder.RoleSubscriber
}
expireTime64, parseErr := strconv.ParseUint(expireTime, 10, 64)
if parseErr != nil {
// if string conversion fails return an error
err = fmt.Errorf("failed to parse expireTime: %s, causing error: %s", expireTime, parseErr)
}
// set timestamps
expireTimeInSeconds := uint32(expireTime64)
currentTimestamp := uint32(time.Now().UTC().Unix())
expireTimestamp = currentTimestamp + expireTimeInSeconds
return channelName, tokentype, uidStr, role, expireTimestamp, err
}
마지막으로, 우리는 parseRtcParams
함수를 채울 것이다.이 함수는 채널 이름, UID를 문자열, 영패 유형 generateRtcToken
또는 uid
, 역할 및 만료 시간으로 사용합니다.이 값을 사용하면 이 함수는 영패 문자열을 생성하기 위해 적당한 Agora RTC Token Builder 함수(
userAccount
/BuildTokenWithUserAccount
를 호출합니다.일단 영패 생성기 함수가 돌아오면, 우리는 먼저 오류를 검사하고, 오류가 없으면, 영패 문자열 값을 되돌려줍니다.func generateRtcToken(channelName, uidStr, tokentype string, role rtctokenbuilder.Role, expireTimestamp uint32) (rtcToken string, err error) {
if tokentype == "userAccount" {
log.Printf("Building Token with userAccount: %s\n", uidStr)
rtcToken, err = rtctokenbuilder.BuildTokenWithUserAccount(appID, appCertificate, channelName, uidStr, role, expireTimestamp)
return rtcToken, err
} else if tokentype == "uid" {
uid64, parseErr := strconv.ParseUint(uidStr, 10, 64)
// check if conversion fails
if parseErr != nil {
err = fmt.Errorf("failed to parse uidStr: %s, to uint causing error: %s", uidStr, parseErr)
return "", err
}
uid := uint32(uid64) // convert uid from uint64 to uint 32
log.Printf("Building Token with uid: %d\n", uid)
rtcToken, err = rtctokenbuilder.BuildTokenWithUID(appID, appCertificate, channelName, uid, role, expireTimestamp)
return rtcToken, err
} else {
err = fmt.Errorf("failed to generate RTC token for Unknown Tokentype: %s", tokentype)
log.Println(err)
return "", err
}
}
RTM 토큰 구축
이어서 우리 계속
BuildTokenWithUID
합시다.위의 코드와 같이 getRtmToken
인용getRtmToken
, 호출gin.Context
을 사용하여 필요한 값을 추출하고 되돌아오는 값을 사용하여 RTM 영패를 생성합니다.여기서 차이점은 우리가 직접 아고라 RTM 영패 생성기를 호출하여 영패 String을 생성한다는 것이다.우리는 아무런 문제가 없도록 오류 검사를 포함하고, 마지막에 응답을 구축할 것입니다.func getRtmToken(c *gin.Context) {
log.Printf("rtm token\n")
// get param values
uidStr, expireTimestamp, err := parseRtmParams(c)
if err != nil {
c.Error(err)
c.AbortWithStatusJSON(400, gin.H{
"message": "Error Generating RTC token: " + err.Error(),
"status": 400,
})
return
}
rtmToken, tokenErr := rtmtokenbuilder.BuildToken(appID, appCertificate, uidStr, rtmtokenbuilder.RoleRtmUser, expireTimestamp)
if tokenErr != nil {
log.Println(err) // token failed to generate
c.Error(err)
errMsg := "Error Generating RTM token: " + tokenErr.Error()
c.AbortWithStatusJSON(400, gin.H{
"error": errMsg,
"status": 400,
})
} else {
log.Println("RTM Token generated")
c.JSON(200, gin.H{
"rtmToken": rtmToken,
})
}
}
다음은 우리 parseRtmParams
를 기입합시다.이 함수는 parseRtmParams
를 인용한 다음 인자를 추출하고 되돌려줍니다.func parseRtmParams(c *gin.Context) (uidStr string, expireTimestamp uint32, err error) {
// get param values
uidStr = c.Param("uid")
expireTime := c.DefaultQuery("expiry", "3600")
expireTime64, parseErr := strconv.ParseUint(expireTime, 10, 64)
if parseErr != nil {
// if string conversion fails return an error
err = fmt.Errorf("failed to parse expireTime: %s, causing error: %s", expireTime, parseErr)
}
// set timestamps
expireTimeInSeconds := uint32(expireTime64)
currentTimestamp := uint32(time.Now().UTC().Unix())
expireTimestamp = currentTimestamp + expireTimeInSeconds
// check if string conversion fails
return uidStr, expireTimestamp, err
}
RTC 및 RTM 토큰 구축
이제 단일 서버에서 RTC와 RTM 영패를 생성할 수 있습니다. 이 두 영패를 단일 요청에서 생성할 수 있도록
gin.Context
을 작성합니다.우리는 getBothTokens
와 매우 비슷한 코드를 사용할 것이지만, 이번에는 RTM 영패를 포함할 것이다.func getBothTokens(c *gin.Context) {
log.Printf("dual token\n")
// get rtc param values
channelName, tokentype, uidStr, role, expireTimestamp, rtcParamErr := parseRtcParams(c)
if rtcParamErr != nil {
c.Error(rtcParamErr)
c.AbortWithStatusJSON(400, gin.H{
"message": "Error Generating RTC token: " + rtcParamErr.Error(),
"status": 400,
})
return
}
// generate the rtcToken
rtcToken, rtcTokenErr := generateRtcToken(channelName, uidStr, tokentype, role, expireTimestamp)
// generate rtmToken
rtmToken, rtmTokenErr := rtmtokenbuilder.BuildToken(appID, appCertificate, uidStr, rtmtokenbuilder.RoleRtmUser, expireTimestamp)
if rtcTokenErr != nil {
log.Println(rtcTokenErr) // token failed to generate
c.Error(rtcTokenErr)
errMsg := "Error Generating RTC token - " + rtcTokenErr.Error()
c.AbortWithStatusJSON(400, gin.H{
"status": 400,
"error": errMsg,
})
} else if rtmTokenErr != nil {
log.Println(rtmTokenErr) // token failed to generate
c.Error(rtmTokenErr)
errMsg := "Error Generating RTC token - " + rtmTokenErr.Error()
c.AbortWithStatusJSON(400, gin.H{
"status": 400,
"error": errMsg,
})
} else {
log.Println("RTC Token generated")
c.JSON(200, gin.H{
"rtcToken": rtcToken,
"rtmToken": rtmToken,
})
}
}
토큰 서버 테스트
터미널 창으로 돌아가서 영패 서버를 실행합시다.
run main.go
서버 실례가 실행된 후에 우리는 단점 목록과 메시지를 볼 수 있습니다: getRtcToken
.현재 저희 서버의 실례가 실행 중입니다. 웹 브라우저를 열고 테스트를 진행하겠습니다.이러한 테스트에 대해 우리는 각종 조회 파라미터를 생략하는 변체를 시도할 것이다.
RTC 노드 테스트
우리는 RTC 영패부터 시작할 것이다.
http://localhost:8080/rtc/testing/publisher/userAccount/1234/
http://localhost:8080/rtc/testing/publisher/uid/1234/
단점은 채널에서 사용할 수 있는 영패를 생성합니다. Listening and serving HTTP on :8080
역할이 testing
및 publisher
의 UID
(문자열과 uint) 사용자가 사용합니다.{
"rtcToken": "0062ec0d84c41c4442d88ba6f5a2beb828bIADJRwbbO8J93uIDi4J305xNXA0A+pVDTPLPavzwsLW3uAZa8+ij4OObIgDqFTEDoOMyXwQAAQAwoDFfAgAwoDFfAwAwoDFfBAAwoDFf"
}
이 영패를 테스트하기 위해서 우리는 사용할 수 있다Agora 1:1 Web Demo.RTM 노드 테스트
이제 RTM 토큰을 테스트합니다.
http://localhost:8080/rtm/1234/
끝점은 영패를 생성합니다. UID가 1234
인 사용자는 이 영패를 사용하여 주어진 1234
RTM에 로그인할 수 있습니다.{
"rtmToken": "0062ec0d84c41c4442d88ba6f5a2beb828bIABSMH0fzaqy7sa0erk8u4Bp6FJ4sO1kQ/o6HCRECBRrzKPg45sAAAAAEAAjAkAEO+cyXwEA6APLozFf"
}
이 영패를 테스트하기 위해서 우리는 사용할 수 있다Agora RTM Tutorial Demo.더블 영패 단점 테스트
우리는 이중 영패 단점을 사용하여 테스트를 완성할 것이다.
http://localhost:8080/rte/testing/publisher/userAccount/1234/
http://localhost:8080/rte/testing/publisher/uid/1234/
끝점은 AppID
및 RTC
영패를 생성하고 사용자는 RTM
UID (문자열 또는 uint) 및 1234
역할의 비디오 채널을 사용할 수 있습니다: testing
.{
"rtcToken": "0062ec0d84c41c4442d88ba6f5a2beb828bIAD33wY6pO+xp6iBY8mbYz2YtOIiRoTTrzdIPF9DEFlSIwZa8+ij4OObIgAQ6e0EX+UyXwQAAQDvoTFfAgDvoTFfAwDvoTFfBADvoTFf",
"rtmToken": "0062ec0d84c41c4442d88ba6f5a2beb828bIABbCwQgl2te3rk0MEDZ2xrPoalb37fFhTqmTIbGeWErWaPg45sAAAAAEAD1WwYBX+UyXwEA6APvoTFf"
}
영패를 테스트하기 위해서 우리는 Agora 1:1 Web Demo RTC 영패에 사용할 수 있고, Agora RTM Tutorial Demo RTM 영패에 사용할 수 있다.끝점을 테스트하면 터미널 창에 모든 요청이 표시됩니다.
완성!
이렇게 해서 우리는 끝났다!코드를 작성하지 않았거나 최종 제품을 함께 보기 싫은 경우 GitHub에 모든 코드를 업로드했습니다Agora Token Service.
제 강좌를 읽는 데 시간을 주셔서 감사합니다. 만약 문제가 있으면 저에게 알려주십시오.만약 당신이 어떤 개선된 공간을 보게 된다면, 언제든지 환매 요청을 제출하세요!
기타 리소스
아고라 토큰에 대한 더 많은 정보.io 응용 프로그램은 Set up Authentication 안내서와 [Agora Advanced guide: How to build a Token]f(https://docs.agora.io/en/Video/token_server_go?platform=Go)(Go를 참조하십시오.
방문도 요청합니다join the Agoira.io Developer Slack community.
Reference
이 문제에 관하여(GoLang을 사용하여 Agora 애플리케이션을 위한 토큰 서버 구축 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/hermes_f/how-to-build-a-token-server-for-agora-applications-using-golang-4db텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)