Преглед изворни кода

[优化]登录采用双token、下发消息优化

chengqian пре 1 година
родитељ
комит
a59e281f52

+ 1 - 1
app/file/controller/file.go

@@ -24,7 +24,7 @@ func (f *file) Distribute(c *gin.Context) {
 	//获取当前用户
 	header := c.GetHeader("Authorization")
 	claims, _ := token.JwtClaims.ParseJwtToken(header)
-	nowUser, _ := cache.GetToken(claims.ID)
+	nowUser, _ := cache.GetNowUser(claims.ID)
 
 	//TODO:校验签名 如果成功则上传否则不上传
 	formFile, err := c.FormFile("file")

+ 6 - 18
app/middleware/token.go

@@ -2,7 +2,6 @@ package middleware
 
 import (
 	"github.com/gin-gonic/gin"
-	"iot_manager_service/util/cache"
 	"iot_manager_service/util/common"
 	"iot_manager_service/util/token"
 	"net/http"
@@ -20,31 +19,20 @@ func AuthMiddleware() gin.HandlerFunc {
 			return
 		}
 		// 从请求头中获取token
-		tokeString := c.GetHeader("Authorization")
-		if tokeString == "" {
-			c.JSON(http.StatusOK, common.ParamsInvalidResponse("Authorization不能为空", nil))
+		tokenString := c.GetHeader("Authorization")
+		if tokenString == "" {
+			c.JSON(http.StatusOK, common.ParamsInvalidResponse("Token不能为空", nil))
 			c.Abort()
 			return
 		}
 		//解析token
-		claims, err := token.JwtClaims.ParseJwtToken(tokeString)
+		_, err := token.JwtClaims.ParseJwtToken(tokenString)
+		//过期或者无效
 		if err != nil {
-			c.JSON(http.StatusOK, common.ParamsInvalidResponse("Authorization解析错误", nil))
+			c.JSON(http.StatusUnauthorized, common.StatusUnauthorized("Token失效", nil))
 			c.Abort()
 			return
 		}
-		//判断是不是最新一次的token,只有最新的有效,否则无效,不放行
-		nowuser, err := cache.GetToken(claims.ID)
-		if nowuser.UUID != claims.UUID || nowuser == nil || err != nil {
-			c.JSON(http.StatusOK, common.ParamsInvalidResponse("Authorization失效", nil))
-			c.Abort()
-			return
-		}
-		//刷新redis过期时间
-		err = cache.RefreshRedisKey(claims.ID)
-		if err != nil {
-			c.JSON(http.StatusOK, common.ParamsInvalidResponse("刷新失败", nil))
-		}
 		c.Next()
 	}
 }

+ 18 - 0
app/user/controller/user.go

@@ -3,6 +3,7 @@ package controller
 import (
 	"fmt"
 	"github.com/gin-gonic/gin"
+	"github.com/google/uuid"
 	"iot_manager_service/app/user/model"
 	"iot_manager_service/app/user/service"
 	"iot_manager_service/util/cache"
@@ -10,6 +11,7 @@ import (
 	"iot_manager_service/util/token"
 	"iot_manager_service/util/websocket"
 	"net/http"
+	"strconv"
 )
 
 var UserController = new(user)
@@ -42,6 +44,22 @@ func (u *user) GetDeptUsers(c *gin.Context) {
 	c.JSON(http.StatusOK, users)
 }
 
+func (u *user) GetNewTokens(c *gin.Context) {
+	header := c.GetHeader("Authorization")
+	claims, _ := token.JwtClaims.ParseJwtToken(header)
+	nowUser, _ := cache.GetNowUser(claims.ID)
+
+	UUID := uuid.New().String()
+	accessToken, _ := token.JwtClaims.CreateJwtToken(strconv.Itoa(nowUser.User.ID), nowUser.User.UserName, UUID, 1)
+	refreshToken, _ := token.JwtClaims.CreateJwtToken(strconv.Itoa(nowUser.User.ID), nowUser.User.UserName, UUID, 24*7)
+	tokens := make(map[string]interface{})
+
+	tokens["accessToken"] = accessToken
+	tokens["refreshToken"] = refreshToken
+
+	c.JSON(http.StatusOK, gin.H{"token": tokens})
+}
+
 func (u *user) Logout(c *gin.Context) {
 	header := c.GetHeader("Authorization")
 	claims, _ := token.JwtClaims.ParseJwtToken(header)

+ 9 - 3
app/user/service/userService.go

@@ -46,11 +46,17 @@ func (s *userService) Login(acc string, pwd string) *common.Errors {
 	//登录成功则生成token
 	UUID := uuid.New().String()
 	USERID := strconv.Itoa(USER.ID)
-	jwtToken, _ := token.JwtClaims.CreateJwtToken(USERID, USER.UserName, UUID)
-	cache.SetToken(USERID, UUID, USER)
+	accessToken, _ := token.JwtClaims.CreateJwtToken(USERID, USER.UserName, UUID, 1)
+	refreshToken, _ := token.JwtClaims.CreateJwtToken(USERID, USER.UserName, UUID, 24*7)
+	cache.SetNowUser(USERID, UUID, USER)
+
+	tokens := make(map[string]interface{})
+	tokens["accessToken"] = accessToken
+	tokens["refreshToken"] = refreshToken
+
 	//TODO:到时候记得修改服务器域名
 	urlWebSocket := "ws://localhost:8085/notice/websocket?userID=" + USERID
-	return common.SuccessResponse("登录成功", gin.H{"token": jwtToken, "websocket": urlWebSocket})
+	return common.SuccessResponse("登录成功", gin.H{"token": tokens, "websocket": urlWebSocket})
 }
 
 func (s *userService) GetPublicKey() *common.Errors {

+ 1 - 0
router/router.go

@@ -29,6 +29,7 @@ func InitRouter(engine *gin.Engine) {
 		sys.POST("/login", user.UserController.Login)
 		sys.POST("/logout", user.UserController.Logout)
 		sys.GET("/getdeptusers", user.UserController.GetDeptUsers)
+		sys.GET("/getnewtokens", user.UserController.GetNewTokens)
 	}
 
 	//文件

+ 3 - 3
util/cache/redis.go

@@ -42,17 +42,17 @@ const (
 )
 
 // 将当前用户存入到redis中
-func SetToken(uid string, uuid string, user *dao.User) {
+func SetNowUser(uid string, uuid string, user *dao.User) {
 	nowuser := model.NowUser{
 		uuid,
 		*user,
 	}
 	marshal, _ := json.Marshal(nowuser)
-	Redis.Set("login:"+uid, marshal, time.Hour*1)
+	Redis.Set("login:"+uid, marshal, time.Hour*24*7)
 }
 
 // 从redis中取出当前用户
-func GetToken(uid string) (*model.NowUser, error) {
+func GetNowUser(uid string) (*model.NowUser, error) {
 	result, _ := Redis.Get("login:" + uid).Result()
 	str := []byte(result)
 	nowuser := model.NowUser{}

+ 8 - 0
util/common/errors.go

@@ -45,6 +45,14 @@ func ParamsInvalidResponse(msg string, data interface{}) *Errors {
 	}
 }
 
+func StatusUnauthorized(msg string, data interface{}) *Errors {
+	return &Errors{
+		Code: 401,
+		Msg:  msg,
+		Data: data,
+	}
+}
+
 func OperationInvalidResponse(msg string, data interface{}) *Errors {
 	return &Errors{
 		Code: CodeOperationInvalid,

+ 4 - 4
util/rsa/rsa.go

@@ -103,11 +103,11 @@ func GetPubKey() (interface{}, error) {
 	if err != nil {
 		panic(err)
 	}
-	publicKeyBlock, _ := pem.Decode(publicKeyBytes)
-	publicKeyDecoded, err := x509.ParsePKIXPublicKey(publicKeyBlock.Bytes)
-
+	//publicKeyBlock, _ := pem.Decode(publicKeyBytes)
+	//publicKeyDecoded, err := x509.ParsePKIXPublicKey(publicKeyBlock.Bytes)
+	s := string(publicKeyBytes)
 	if err != nil {
 		panic(err)
 	}
-	return publicKeyDecoded, nil
+	return s, nil
 }

+ 5 - 3
util/token/token.go

@@ -15,6 +15,7 @@ type jwtClaims struct {
 	ID       string
 	UserName string
 	UUID     string
+	Time     time.Time
 }
 
 var (
@@ -27,20 +28,21 @@ var (
 )
 
 // CreateJwtToken 生成一个jwttoken
-func (jwtClaims) CreateJwtToken(id string, userName string, uuid string) (string, error) {
+func (jwtClaims) CreateJwtToken(id string, userName string, uuid string, ti time.Duration) (string, error) {
 
 	// 定义过期时间
-	//expireToken := time.Now().Add(time.Minute * 1).Unix()
+	expireToken := time.Now().Add(time.Hour * ti).Unix()
 
 	claims := jwtClaims{
 		&jwt.StandardClaims{
 			NotBefore: int64(time.Now().Unix() - 1000), // token信息生效时间
-			ExpiresAt: 0,                               // 过期时间永不过期
+			ExpiresAt: expireToken,                     // 过期时间0=永不过期
 			Issuer:    "lc_veterans",                   // 发布者
 		},
 		id,
 		userName,
 		uuid,
+		time.Now(),
 	}
 	// 对自定义claims加密,jwt.SigningMethodHS256是加密算法得到第二部分
 	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)

+ 1 - 1
util/websocket/websocket.go

@@ -80,8 +80,8 @@ func SendMessage(id, msg string) {
 	}
 	// 发送消息
 	err := conn.WriteJSON(msg)
+	//连接关闭
 	if err != nil {
-		log.Println("Error sending message to", id, ":", err)
 		// 发送失败,存储为离线消息
 		StoreOfflineMessage(id, msg)
 	}