feat: self-connection blocking API support (token-device internal endpoint, jti)
This commit is contained in:
1 parent
37b9991d0e
commit
9e34bdce9e
6 files changed
+73
-1
No files matched your search
+1
-1
@@ -1,6 +1,6 @@
|
||||
lang: "zh-CN"
|
||||
app:
|
||||
web-client: 1 # 1:启用 0:禁用
|
||||
web-client: 0 # 1:启用 0:禁用(DMCA 后端永久禁用,代码强制为 0,此配置已失效)
|
||||
register: false #是否开启注册
|
||||
register-status: 1 # 注册用户默认状态 1:启用 2:禁用
|
||||
captcha-threshold: 3 # <0:disabled, 0 always, >0:enabled
|
||||
|
||||
@@ -91,6 +91,8 @@ func Init(rowVal *Config, path string) *viper.Viper {
|
||||
if err := v.Unmarshal(rowVal); err != nil {
|
||||
panic(fmt.Errorf("Fatal error config: %s \n", err))
|
||||
}
|
||||
// webclient2 因 DMCA 已移除前端资源,永久禁用,不再受配置文件或环境变量控制
|
||||
rowVal.App.WebClient = 0
|
||||
rowVal.Rustdesk.LoadKeyFile()
|
||||
rowVal.Admin.Init()
|
||||
return v
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||
)
|
||||
|
||||
type Internal struct {
|
||||
}
|
||||
|
||||
// localOnly 仅允许本机/容器内回环访问
|
||||
func (in *Internal) localOnly(c *gin.Context) bool {
|
||||
ip := c.RemoteIP()
|
||||
return ip == "127.0.0.1" || ip == "::1"
|
||||
}
|
||||
|
||||
// TokenDevice 根据token查询登录设备ID,供hbbs自连拦截内部调用
|
||||
// @Tags 内部接口
|
||||
// @Summary 根据token查询设备ID
|
||||
// @Description 仅供hbbs在容器内调用,需回环地址与共享密钥
|
||||
// @Param token query string true "访问令牌"
|
||||
// @Success 200 {object} map[string]string
|
||||
// @Failure 403 {object} map[string]string
|
||||
// @Failure 404 {object} map[string]string
|
||||
// @Router /api/internal/token-device [get]
|
||||
func (in *Internal) TokenDevice(c *gin.Context) {
|
||||
if !in.localOnly(c) {
|
||||
c.JSON(http.StatusForbidden, gin.H{"error": "forbidden"})
|
||||
return
|
||||
}
|
||||
// 共享密钥:hbbs 通过 RUSTDESK_API_JWT_KEY 持有同一密钥
|
||||
if global.Config.Jwt.Key == "" || c.GetHeader("X-Secret") != global.Config.Jwt.Key {
|
||||
c.JSON(http.StatusForbidden, gin.H{"error": "forbidden"})
|
||||
return
|
||||
}
|
||||
token := c.Query("token")
|
||||
if token == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "token required"})
|
||||
return
|
||||
}
|
||||
deviceId := service.AllService.UserService.GetDeviceIdByToken(token)
|
||||
if deviceId == "" {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "not found"})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"device_id": deviceId})
|
||||
}
|
||||
@@ -73,6 +73,12 @@ func ApiInit(g *gin.Engine) {
|
||||
frg.POST("/audit/file", au.AuditFile)
|
||||
}
|
||||
|
||||
{
|
||||
in := &api.Internal{}
|
||||
// 仅供hbbs容器内调用:token -> device_id(自连拦截用)
|
||||
frg.GET("/internal/token-device", in.TokenDevice)
|
||||
}
|
||||
|
||||
frg.Use(middleware.RustAuth())
|
||||
{
|
||||
u := &api.User{}
|
||||
|
||||
@@ -3,6 +3,7 @@ package jwt
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
"github.com/google/uuid"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -33,6 +34,9 @@ func (s *Jwt) GenerateToken(userId uint) string {
|
||||
UserId: userId,
|
||||
RegisteredClaims: jwt.RegisteredClaims{
|
||||
ExpiresAt: jwt.NewNumericDate(time.Now().Add(s.TokenExpireDuration)),
|
||||
// 每次登录生成唯一 jti,避免同一账号同秒多次登录产生相同 token,
|
||||
// 导致 UserToken 表中 token 无法区分设备
|
||||
ID: uuid.NewString(),
|
||||
},
|
||||
})
|
||||
token, err := t.SignedString(s.Key)
|
||||
|
||||
@@ -85,6 +85,16 @@ func (us *UserService) InfoByAccessToken(token string) (*model.User, *model.User
|
||||
return u, ut
|
||||
}
|
||||
|
||||
// GetDeviceIdByToken 根据token查询登录设备ID,供hbbs自连拦截内部调用
|
||||
func (us *UserService) GetDeviceIdByToken(token string) string {
|
||||
ut := &model.UserToken{}
|
||||
DB.Where("token = ?", token).First(ut)
|
||||
if ut.Id == 0 || ut.ExpiredAt < time.Now().Unix() {
|
||||
return ""
|
||||
}
|
||||
return ut.DeviceId
|
||||
}
|
||||
|
||||
// GenerateToken 生成token
|
||||
func (us *UserService) GenerateToken(u *model.User) string {
|
||||
if len(Jwt.Key) > 0 {
|
||||
|
||||
Reference in new issue
Block a user