package controller import ( "fmt" "github.com/gin-gonic/gin" "github.com/golang-jwt/jwt" "strconv" "time" "iot_manager_service/app/system/model" "iot_manager_service/config" "iot_manager_service/util" "net/http" "strings" ) var Auth = new(auth) type auth struct{} type JwtToken struct { jwt.StandardClaims TenantId string `json:"tenant_id"` UserId int64 `json:"user_id"` TokenType string `json:"token_type"` ClientId string `json:"client_id"` RoleId string `json:"role_id"` RoleName string `json:"role_name"` DeptId string `json:"dept_id"` PostId string `json:"post_id"` OauthId string `json:"oauth_id"` Account string `json:"account"` UserName string `json:"user_name"` NickName string `json:"nick_name"` Random string `json:"random"` } func (c *auth) Token(ctx *gin.Context) { tenantId := ctx.Query("tenantId") userName := ctx.Query("username") password := ctx.Query("password") grantType := ctx.Query("grant_type") refreshToken := ctx.Query("refresh_token") // 校验连续登录失败次数 checkLock() userType := ctx.GetHeader(model.UserTypeHeaderKey) token := model.Token{ TenantId: tenantId, UserName: userName, Password: password, GrantType: grantType, RefreshToken: refreshToken, UserType: userType, } userInfo, err := grant(token, ctx) if err != nil { ctx.JSON(http.StatusOK, err) return } if userInfo == nil || userInfo.ID == 0 { ctx.JSON(http.StatusOK, util.NormalResponse(http.StatusBadRequest, model.UserNotFound, nil)) return } if len(userInfo.Roles) == 0 { ctx.JSON(http.StatusOK, util.NormalResponse(http.StatusBadRequest, model.UserHasNoRole, nil)) return } // access token过期时间2小时 random := util.RandomString(8) jwtToken, e := getAccessToken(*userInfo, random) if e != nil { ctx.JSON(http.StatusOK, util.NormalResponse(http.StatusBadRequest, e.Error(), nil)) return } // redis记录缓存2小时 util.Redis.Set(getAccessTokenKey(userInfo.TenantId, userInfo.ID, random), jwtToken, 2*time.Hour) ctx.JSON(http.StatusOK, model.RspToken{ TenantId: userInfo.TenantId, UserId: strconv.FormatInt(userInfo.ID, 10), DeptId: userInfo.DeptId, PostId: userInfo.PostId, RoleId: userInfo.RoleId, OauthId: userInfo.OauthId, Account: userInfo.Account, UserName: userInfo.Name, NickName: userInfo.RealName, RoleName: userInfo.Roles[0], Avatar: userInfo.Avatar, AccessToken: jwtToken, RefreshToken: getRefreshToken(*userInfo), TokenType: model.BEARER, ExpiresIn: 7200, License: "", }) } //checkLock 校验用户登录失败次数 func checkLock() { } func getAccessTokenKey(tenantId string, uId int64, random string) string { return fmt.Sprintf("access_token_%s_%d_%s", tenantId, uId, random) } func getAccessToken(info model.UserInfo, random string) (string, error) { jwtToken := JwtToken{StandardClaims: jwt.StandardClaims{ Audience: "audience", ExpiresAt: time.Now().Add(2 * time.Hour).Unix(), Issuer: "issuser", NotBefore: time.Now().Unix(), }, UserId: info.ID, TenantId: info.TenantId, TokenType: "access_token", ClientId: "saber", RoleId: info.RoleId, RoleName: info.Roles[0], DeptId: info.DeptId, PostId: info.PostId, OauthId: info.OauthId, Account: info.Account, UserName: info.Account, NickName: info.RealName, Random: random, } claims := jwt.NewWithClaims(jwt.SigningMethodHS512, jwtToken) return claims.SignedString([]byte(config.Instance().Server.TokenSign)) } func getRefreshToken(info model.UserInfo) string { claims := jwt.NewWithClaims(jwt.SigningMethodHS512, jwt.MapClaims{ model.Iss: "issuser", model.Aud: "audience", model.ClientId: "saber", model.TokenType: "refresh_token", model.UserId: info.ID, model.Exp: time.Now().Add(7 * 24 * time.Hour).Unix(), model.Nbf: time.Now().Unix(), }) token, _ := claims.SignedString([]byte(config.Instance().Server.TokenSign)) return token } func grant(token model.Token, ctx *gin.Context) (*model.UserInfo, *util.Errors) { info := &model.UserInfo{} key := ctx.GetHeader(model.CaptchaHeaderKey) code := ctx.GetHeader(model.CaptchaHeaderCode) // 获取验证码 redisCode := util.Redis.Get(model.CaptchaKey + key).String() // 判断验证码 if config.Instance().Server.CodeEnable && (code == "" || !strings.EqualFold(redisCode, code)) { return nil, util.NormalResponse(http.StatusBadRequest, model.CaptchaNotCorrect, nil) } if token.UserName != "" && token.Password != "" { // 获取租户信息 //Tenant tenant = tenantService.getByTenantId(tenantId); //if (TokenUtil.judgeTenant(tenant)) { // throw new ServiceException(TokenUtil.USER_HAS_NO_TENANT_PERMISSION); //} // 获取用户类型 // 根据不同用户类型调用对应的接口返回数据,用户可自行拓展 // info.Auth = userService.GetUser(auth.tenantId, auth.UserName, auth.password) } //测试代码start info.TenantId = "000000" info.ID = 11112222 info.Roles = []string{"admin"} // 测试代码end //todo 操作记录 return info, nil } func (c *auth) Logout(ctx *gin.Context) { emptyKeyFunc := func(t *jwt.Token) (interface{}, error) { return []byte(config.Instance().Server.TokenSign), nil } authorization := ctx.GetHeader("Authorization") token, err := jwt.ParseWithClaims(authorization, &JwtToken{}, emptyKeyFunc) if err != nil { ctx.JSON(http.StatusUnauthorized, util.NormalResponse(http.StatusUnauthorized, err.Error(), nil)) return } jwtToken := token.Claims.(*JwtToken) err = util.Redis.Del(getAccessTokenKey(jwtToken.TenantId, jwtToken.UserId, jwtToken.Random)).Err() //todo 操作记录 ctx.JSON(http.StatusOK, util.SuccessResponse("", nil)) } func (c *auth) Captcha(ctx *gin.Context) { ctx.JSON(0, nil) }