Merge branch 'refs/heads/feat-docker'
This commit is contained in:
commit
f165eecf89
|
|
@ -0,0 +1,33 @@
|
||||||
|
# 第一阶段:使用最新Go版本构建
|
||||||
|
FROM docker.1ms.run/golang:1.24 AS builder
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
ENV GOPROXY=https://goproxy.cn,direct
|
||||||
|
|
||||||
|
|
||||||
|
# 复制go.mod和go.sum以缓存依赖
|
||||||
|
COPY go.mod go.sum ./
|
||||||
|
RUN go mod download
|
||||||
|
|
||||||
|
# 复制源代码并构建
|
||||||
|
COPY . .
|
||||||
|
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -ldflags="-s -w" -o videoplayer .
|
||||||
|
|
||||||
|
# 第二阶段:生产环境(最小化镜像)
|
||||||
|
FROM scratch
|
||||||
|
|
||||||
|
# 复制配置文件
|
||||||
|
COPY --from=builder /app/saw-ai.conf /home/saw/saw-ai.conf
|
||||||
|
|
||||||
|
# 复制二进制文件
|
||||||
|
COPY --from=builder /app/videoplayer /home/videoplayer/videoplayer
|
||||||
|
|
||||||
|
# 设置工作目录
|
||||||
|
WORKDIR /home/videoplayer
|
||||||
|
|
||||||
|
# 暴露端口
|
||||||
|
EXPOSE 8083
|
||||||
|
|
||||||
|
# 运行应用
|
||||||
|
CMD ["./videoplayer"]
|
||||||
74
main.go
74
main.go
|
|
@ -2,6 +2,7 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/golang-jwt/jwt"
|
"github.com/golang-jwt/jwt"
|
||||||
|
|
@ -100,29 +101,23 @@ func JWTAuthMiddleware() gin.HandlerFunc {
|
||||||
}
|
}
|
||||||
// 从请求头中获取 JWT 令牌
|
// 从请求头中获取 JWT 令牌
|
||||||
tokenString := c.Request.Header.Get("token")
|
tokenString := c.Request.Header.Get("token")
|
||||||
|
|
||||||
//请求方式为get时,从url中获取token
|
//请求方式为get时,从url中获取token
|
||||||
if tokenString == "" {
|
if tokenString == "" {
|
||||||
tokenString = c.Query("token")
|
tokenString = c.Query("token")
|
||||||
}
|
}
|
||||||
//如果请求为login或register,则不需要验证token
|
for k, _ := range proto.Url_map {
|
||||||
//for k, _ := range proto.Url_map {
|
if strings.Contains(c.Request.URL.Path, k) {
|
||||||
// if strings.Contains(c.Request.URL.Path, k) {
|
log.Println("need not check token:", c.Request.URL.Path)
|
||||||
// c.Next()
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
if proto.Url_map[c.Request.URL.Path] == true { //查看是否在不需要token的url中
|
|
||||||
c.Next()
|
c.Next()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
//if proto.Url_map[c.Request.URL.Path] == true { //查看是否在不需要token的url中
|
||||||
|
// c.Next()
|
||||||
|
// return
|
||||||
|
//}
|
||||||
if tokenString == "" {
|
if tokenString == "" {
|
||||||
//c.AbortWithStatus(200)
|
c.AbortWithStatusJSON(http.StatusOK, gin.H{"message": "unauthorized", "error": "token is empty", "code": proto.TokenIsNull})
|
||||||
c.JSON(200, gin.H{
|
|
||||||
"message": "Unauthorized",
|
|
||||||
"error": "token is empty",
|
|
||||||
"code": proto.TokenIsNull,
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if proto.Config.TOKEN_USE_REDIS {
|
if proto.Config.TOKEN_USE_REDIS {
|
||||||
|
|
@ -132,7 +127,6 @@ func JWTAuthMiddleware() gin.HandlerFunc {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//查看token是否在超级token中
|
//查看token是否在超级token中
|
||||||
if worker.IsContainSet("super_permission_tokens", tokenString) {
|
if worker.IsContainSet("super_permission_tokens", tokenString) {
|
||||||
sId := c.Request.Header.Get("super_id")
|
sId := c.Request.Header.Get("super_id")
|
||||||
|
|
@ -147,40 +141,52 @@ func JWTAuthMiddleware() gin.HandlerFunc {
|
||||||
idFloat64 := float64(id)
|
idFloat64 := float64(id)
|
||||||
//查看s_id类型
|
//查看s_id类型
|
||||||
c.Set("id", idFloat64)
|
c.Set("id", idFloat64)
|
||||||
|
c.Set("user_id", id)
|
||||||
c.Next()
|
c.Next()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 使用加密secret 解析 JWT 令牌
|
// 使用加密secret 解析 JWT 令牌
|
||||||
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
|
//token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
|
||||||
|
// return proto.SigningKey, nil
|
||||||
|
//})
|
||||||
|
token, err := jwt.Parse(tokenString, func(t *jwt.Token) (interface{}, error) {
|
||||||
|
// 验证签名算法
|
||||||
|
if _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok {
|
||||||
|
return nil, jwt.ErrSignatureInvalid
|
||||||
|
}
|
||||||
return proto.SigningKey, nil
|
return proto.SigningKey, nil
|
||||||
})
|
})
|
||||||
|
// 错误处理
|
||||||
// 验证令牌
|
if err != nil {
|
||||||
if err != nil || !token.Valid {
|
var ve *jwt.ValidationError
|
||||||
c.AbortWithStatusJSON(http.StatusOK, gin.H{
|
if errors.As(err, &ve) {
|
||||||
"message": "NOT_LOGIN",
|
switch {
|
||||||
"error": "Invalid token",
|
case ve.Errors&jwt.ValidationErrorMalformed != 0:
|
||||||
"code": proto.TokenExpired,
|
c.AbortWithStatusJSON(http.StatusOK, gin.H{"error": "Malformed token:" + err.Error(), "code": proto.TokenInvalid})
|
||||||
})
|
case ve.Errors&jwt.ValidationErrorExpired != 0:
|
||||||
|
c.AbortWithStatusJSON(http.StatusOK, gin.H{"error": "Token expired:" + err.Error(), "code": proto.TokenExpired})
|
||||||
|
case ve.Errors&jwt.ValidationErrorNotValidYet != 0:
|
||||||
|
c.AbortWithStatusJSON(http.StatusOK, gin.H{"error": "Token not active yet:" + err.Error(), "code": proto.TokenInvalid})
|
||||||
|
default:
|
||||||
|
c.AbortWithStatusJSON(http.StatusOK, gin.H{"error": "Invalid token:" + err.Error(), "code": proto.TokenInvalid})
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 将用户信息添加到上下文中
|
// 将用户信息添加到上下文中
|
||||||
c.Set("id", token.Claims.(jwt.MapClaims)["id"])
|
id := token.Claims.(jwt.MapClaims)["id"]
|
||||||
c.Set("username", token.Claims.(jwt.MapClaims)["username"])
|
c.Set("id", id)
|
||||||
|
c.Set("user_id", int(id.(float64)))
|
||||||
|
|
||||||
if UserFuncIntercept(int(token.Claims.(jwt.MapClaims)["id"].(float64)), c.Request.URL.Path) {
|
if UserFuncIntercept(int(id.(float64)), c.Request.URL.Path) {
|
||||||
c.AbortWithStatusJSON(http.StatusOK, gin.H{
|
c.AbortWithStatusJSON(http.StatusOK, gin.H{"message": "unauthorized", "error": "no function permission", "code": proto.NoPermission})
|
||||||
"message": "no function permission",
|
|
||||||
"error": "no permission",
|
|
||||||
"code": proto.NoPermission,
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 继续处理请求
|
// 继续处理请求
|
||||||
c.Next()
|
c.Next()
|
||||||
|
//log.Println("JWT token is valid, user ID:", token.Claims.(jwt.MapClaims)["id"], " path:", c.Request.URL.Path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
16
vp.conf
16
vp.conf
|
|
@ -1,15 +1,21 @@
|
||||||
{
|
{
|
||||||
"db":0,
|
"db":0,
|
||||||
"mysql_dsn":"video_t2:2t2SKHmWEYj2xFKF@tcp(127.0.0.1:3306)/video_t2?charset=utf8mb4&parseTime=True&loc=Local",
|
"mysql_dsn":"vp-db:ZcxsP7s7kaBxxDPc@tcp(tx.ljsea.top:3306)/vp-db?charset=utf8mb4&parseTime=True&loc=Local",
|
||||||
"pg_dsn":"host=localhost user=video_t2 dbname=video_t2 password=2t2SKHmWEYj2xFKF port=5432 TimeZone=Asia/Shanghai",
|
"pg_dsn":"host=localhost user=video_t2 dbname=video_t2 password=2t2SKHmWEYj2xFKF port=5432 TimeZone=Asia/Shanghai",
|
||||||
"redis_addr":"127.0.0.1:6379",
|
"redis_addr":"host.docker.internal:6379",
|
||||||
"redis_db":2,
|
"redis_db":2,
|
||||||
"redis_user_pw":true,
|
"redis_user_pw":true,
|
||||||
"token_use_redis":true,
|
"token_use_redis":false,
|
||||||
"redis_password":"lj502138",
|
"redis_password":"lj502138",
|
||||||
"token_secret":"mfjurnc_32ndj9dfhj",
|
"token_secret":"mfjurnc_32ndj9dfhj",
|
||||||
"cid_base_dir":"/home/lijun/cid/",
|
"cid_base_dir":"/home/lijun/cid/",
|
||||||
"file_base_dir":"/home/lijun/file/",
|
"file_base_dir":"/home/lijun/file/",
|
||||||
"monitor":false,
|
"monitor": true,
|
||||||
"server_port":"8083"
|
"server_port": "8083",
|
||||||
|
"log_save_days": 3,
|
||||||
|
"user_type": "slave",
|
||||||
|
"master_server_domain": "tx.ljsea.top",
|
||||||
|
"user_sync_time": 0,
|
||||||
|
"server_name": "home_vp_docker_server",
|
||||||
|
"monitor_server_token": "627gyf3488h"
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue