Commit 3ce89231 by zhangjiec

增加token生成和验证

parent ca8e0ad0
...@@ -4,14 +4,6 @@ import ( ...@@ -4,14 +4,6 @@ import (
"sync" "sync"
) )
/*****************************************************后台管理账户*/
//var adminMap sync.Map //后台管理账户
//type AdminStruct struct {
// AdminID int
//
//}
/*---------------------------------------------------------------*/
/*********************************************************代理商**/ /*********************************************************代理商**/
//// AgentMap 代理商 //// AgentMap 代理商
//var AgentMap sync.Map //var AgentMap sync.Map
...@@ -34,7 +26,7 @@ type AreaServiceStruct struct { // ...@@ -34,7 +26,7 @@ type AreaServiceStruct struct { //
ServiceID uint8 //服务项目 1公话 2定位 3饮水 4POS ......... ServiceID uint8 //服务项目 1公话 2定位 3饮水 4POS .........
OperatorID int32 //运营商ID OperatorID int32 //运营商ID
Name string //服务名字(例宿舍135栋饮水)name Name string //服务名字(例宿舍135栋饮水)name
Status bool //状态 Status uint8 //状态 1正式2测试3暂停
} }
/*---------------------------------------------------------------*/ /*---------------------------------------------------------------*/
...@@ -48,13 +40,13 @@ type AdminStruct struct { ...@@ -48,13 +40,13 @@ type AdminStruct struct {
//Phone string //Phone string
//OperatorID []int //OperatorID []int
SystemAuth int //系统角色权限 SystemAuth int //系统角色权限
AreaServiceAuth [][]int //area_service_id,role_id AreaServiceAuth [][]int //area_service_id,admin_role_id
} }
/*---------------------------------------------------------------*/ /*---------------------------------------------------------------*/
// roleAuthMap /****************************角色权限(包含区域和系统角色)*/ // roleAuthMap /****************************角色权限(包含区域和系统角色)*/
var roleAuthMap sync.Map //role_id 作为KEY var adminRoleAuthMap sync.Map //admin_role_id 作为KEY
type RoleAuthStruct struct { type RoleAuthStruct struct {
Name string Name string
// 考虑接口、菜单、按钮权限 // 考虑接口、菜单、按钮权限
...@@ -85,8 +77,8 @@ type WechatCustomerStruct struct { ...@@ -85,8 +77,8 @@ type WechatCustomerStruct struct {
/****************************************************************/ /****************************************************************/
/***************************************************卡用户(学生)**/ /***************************************************卡用户(学生、教师、职工)**/
var cardUserMap sync.Map //卡用户 CardUserID卡用户ID(int) 作为KEY var cardUserMap sync.Map //卡用户 CardUserID卡用户ID(int) 作为KEY 纯卡用户可以不绑定微信
type CardUserType struct { type CardUserType struct {
// WechatUnionID string // WechatUnionID string
// AreaID int // AreaID int
......
package main package main
import ( import (
"dc_golang_server_1/api"
"dc_golang_server_1/cache" "dc_golang_server_1/cache"
"dc_golang_server_1/config" "dc_golang_server_1/config"
"dc_golang_server_1/dbmodel" "dc_golang_server_1/dbmodel"
"dc_golang_server_1/devproduct/dcphone20" "dc_golang_server_1/devproduct/dcphone20"
"dc_golang_server_1/logger" "dc_golang_server_1/logger"
"dc_golang_server_1/web"
"os" "os"
"runtime" "runtime"
"syscall" "syscall"
...@@ -78,5 +78,5 @@ func main() { // ...@@ -78,5 +78,5 @@ func main() { //
dcphone20.NewDCPhone20() dcphone20.NewDCPhone20()
//dcdrinking60.NewDCDrinking60() //dcdrinking60.NewDCDrinking60()
api.InitRouter() web.InitRouter()
} }
package middleware
import (
"dc_golang_server_1/util"
"fmt"
"github.com/gin-gonic/gin"
"math/rand"
"time"
)
const jeffWTKey = "jeffWT@666%b;'~+"
const jeffWTTable = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
type JeffWTInfo struct {
UID int32
UserName string // 最长32字节
CreatTime uint64
ExpireTime uint64
}
// 定义错误
//var (
// TokenExpired error = errors.New("Token已过期,请重新登录")
// TokenNotValidYet error = errors.New("Token无效,请重新登录")
// TokenMalformed error = errors.New("Token不正确,请重新登录")
// TokenInvalid error = errors.New("这不是一个token,请重新登录")
//)
// CreateToken 生成token
func CreateToken(info JeffWTInfo) string {
info.UID = ^info.UID
info.CreatTime = ^info.CreatTime
info.ExpireTime = ^info.ExpireTime
var clear [52]byte //= make([]byte, 20)
var str [30]byte
for i := 0; i < len(info.UserName); i++ {
str[i] = info.UserName[i] + (uint8(i) << 2)
}
r := rand.New(rand.NewSource(time.Now().UnixNano()))
clear[0] = str[18] + 76
clear[1] = byte(info.CreatTime >> 16)
clear[2] = byte(info.ExpireTime >> 8)
clear[3] = byte(info.UID >> 24)
clear[4] = str[29] + 60
clear[5] = byte(r.Intn(256))
clear[6] = byte(info.UID >> 8)
clear[7] = byte(info.ExpireTime)
clear[8] = byte(r.Intn(256))
clear[9] = str[9]
clear[10] = byte(r.Intn(256))
clear[11] = byte(info.CreatTime >> 24)
clear[12] = byte(info.CreatTime)
clear[13] = byte(info.ExpireTime >> 24)
clear[14] = 0x16 + clear[2] - clear[0] + clear[11] - clear[7] - clear[12] + clear[10]
clear[15] = byte(r.Intn(256))
clear[16] = byte(info.UID >> 16)
clear[17] = byte(info.CreatTime >> 8)
clear[18] = byte(info.ExpireTime >> 16)
clear[19] = str[0] + 90
clear[29] = str[28] + clear[10] + clear[8]
clear[29] = str[25]
clear[29] = str[22]
clear[29] = str[13]
clear[29] = str[12]
clear[29] = byte(info.UID)
clear[29] = str[0]
clear[29] = str[1]
clear[29] = str[2]
clear[29] = str[3]
clear[29] = str[4]
clear[29] = str[5]
clear[29] = str[6]
clear[29] = str[7]
clear[29] = str[8]
clear[29] = str[9]
clear[29] = str[10]
clear[29] = str[11]
clear[29] = str[12]
clear[29] = str[13]
clear[29] = str[14]
// todo 根据缓存来,记得CRC
fmt.Println(clear[:19])
util.GetCRC(clear[:19], 19)
s := util.EncryptBytesToBase64URL(clear[:], jeffWTKey)
//fmt.Println(s)
result := make([]byte, 32)
copy(result[:8], s[20:])
copy(result[11:], s[:20])
result[8] = jeffWTTable[r.Intn(64)]
result[9] = jeffWTTable[r.Intn(64)]
result[10] = jeffWTTable[r.Intn(64)]
result[31] = jeffWTTable[r.Intn(64)]
return string(result)
}
// ParserToken 解析token
//func (j *JWT) ParserToken(tokenString string) (*MyClaims, error) {
// token, err := jwt.ParseWithClaims(tokenString, &MyClaims{}, func(token *jwt.Token) (interface{}, error) {
// return j.JwtKey, nil
// })
//
// if err != nil {
// if ve, ok := err.(*jwt.ValidationError); ok {
// if ve.Errors&jwt.ValidationErrorMalformed != 0 {
// return nil, errors.New("Token不正确,请重新登录")
// } else if ve.Errors&jwt.ValidationErrorExpired != 0 {
// // Token is expired
// return nil, errors.New("Token已过期,请重新登录")
// } else if ve.Errors&jwt.ValidationErrorNotValidYet != 0 {
// return nil, errors.New("Token无效,请重新登录")
// } else {
// return nil, errors.New("这不是一个token,请重新登录")
// }
// }
// }
//
// if token != nil {
// if claims, ok := token.Claims.(*MyClaims); ok && token.Valid {
// return claims, nil
// }
// return nil, errors.New("这不是一个token,请重新登录")
// }
//
// return nil, errors.New("这不是一个token,请重新登录")
//}
// JwtToken jwt中间件
func JwtToken() gin.HandlerFunc {
return func(c *gin.Context) {
//tokenHeader := c.Request.Header.Get("Authorization")
//if tokenHeader == "" {
// c.JSON(http.StatusOK, gin.H{
// "status": 1004,
// "message": "TOKEN不存在",
// })
// c.Abort()
// return
//}
//
//checkToken := strings.Split(tokenHeader, " ")
//if len(checkToken) == 0 {
// c.JSON(http.StatusOK, gin.H{
// "status": 1007,
// "message": "TOKEN格式错误",
// })
// c.Abort()
// return
//}
//
//if len(checkToken) != 2 || checkToken[0] != "Bearer" {
// c.JSON(http.StatusOK, gin.H{
// "status": 1007,
// "message": "TOKEN格式错误",
// })
// c.Abort()
// return
//}
//
//j := NewJWT()
//// 解析token
//claims, err := j.ParserToken(checkToken[1])
//if err != nil {
// //if err == TokenExpired {
// // c.JSON(http.StatusOK, gin.H{
// // "status": 500,
// // "message": "token授权已过期,请重新登录",
// // "data": nil,
// // })
// // c.Abort()
// // return
// //}
//
// c.JSON(http.StatusOK, gin.H{
// "status": 500,
// "message": err.Error(),
// "data": nil,
// })
// c.Abort()
// return
//}
//
//c.Set("username", claims)
c.Next()
}
}
//var JwtKey = []byte(utils.JwtKey)
//
//type MyClaims struct {
// Username string `json:"username"`
// jwt.StandardClaims
//}
//
//// 生成token
//func SetToken(username string) (string,int){
// setClaims := MyClaims{
// username,
// jwt.StandardClaims{
// ExpiresAt: time.Now().Add(10*time.Hour).Unix(),
// Issuer: "ginblog",
// },
// }
//
// reqClaim := jwt.NewWithClaims(jwt.SigningMethodHS256, setClaims)
// token,err := reqClaim.SignedString(JwtKey)
// if err != nil {
// return "",errmsg.ERROR
// }
// return token,errmsg.SUCCSE
//}
//
//// 验证token
//func CheckToken(token string) (*MyClaims, int){
// if token == "" || token == "null"{
// return nil,errmsg.ERROR
// }
// setToken,_ := jwt.ParseWithClaims(token, &MyClaims{}, func(token *jwt.Token) (interface{}, error) {
// return JwtKey, nil
// })
// if key,_ := setToken.Claims.(*MyClaims); setToken.Valid{
// return key,errmsg.SUCCSE
// }
// return nil,errmsg.ERROR
//}
//
//// jwt中间件
//func JwtToken() gin.HandlerFunc{
// var code int
// return func(c *gin.Context) {
// tokenHeader := c.Request.Header.Get("Authorization")
//
// if tokenHeader == "" {
// code = errmsg.ERROR_TOKEN_EXIST
// c.JSON(http.StatusOK,gin.H{
// "code":code,
// "message":errmsg.GetErrMsg(code),
// })
// c.Abort()
// return
// }
// checkToken := strings.SplitN(tokenHeader, " ", 2)
// if len(checkToken) != 2 && checkToken[0] != "Bearer" {
// code = errmsg.ERROR_TOKEN_TYPE_WRONG
// c.JSON(http.StatusOK,gin.H{
// "code":code,
// "message":errmsg.GetErrMsg(code),
// })
// c.Abort()
// return
// }
// key,tCode := CheckToken(checkToken[1])
// if tCode == errmsg.ERROR {
// code = errmsg.ERROR_TOKEN_WRONG
// c.JSON(http.StatusOK,gin.H{
// "code":code,
// "message":errmsg.GetErrMsg(code),
// })
// c.Abort()
// return
// }
// if time.Now().Unix() > key.ExpiresAt {
// code = errmsg.ERROR_TOKEN_RUNTIME
// c.JSON(http.StatusOK,gin.H{
// "code":code,
// "message":errmsg.GetErrMsg(code),
// })
// c.Abort()
// return
// }
//
// c.Set("username",key.Username)
// c.Next()
// }
//}
package middleware package web
import ( import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
......
package web
const (
SUCCSE = 200
ERROR = 500
// code = 1000...用户模块的错误
ERROR_USERNAME_USED = 1001
ERROR_PASSWORD_WRONG = 1002
ERROR_USER_NOT_EXIST = 1003
ERROR_TOKEN_EXIST = 1004
ERROR_TOKEN_RUNTIME = 1005
ERROR_TOKEN_WRONG = 1006
ERROR_TOKEN_TYPE_WRONG = 1007
ERROR_USER_NO_RIGHT = 1008
// code = 2000...XXXXX模块的错误
// code = 3000...XXXXX模块的错误
)
//var codeMsg = map[int]string{
// SUCCSE: "OK",
// ERROR: "FAIL",
// ERROR_USERNAME_USED: "用户名已存在!",
// ERROR_PASSWORD_WRONG: "密码错误",
// ERROR_USER_NOT_EXIST: "用户不存在",
// ERROR_TOKEN_EXIST: "TOKEN不存在",
// ERROR_TOKEN_RUNTIME: "TOKEN已过期",
// ERROR_TOKEN_WRONG: "TOKEN不正确",
// ERROR_TOKEN_TYPE_WRONG: "TOKEN格式错误",
// ERROR_USER_NO_RIGHT: "用户没有权限",
//}
This diff is collapsed. Click to expand it.
一、管理后台接口 一、管理后台接口
1. 后台用户登录 1. 后台用户登录
传:LoginAccount、Password、验证码 传:LoginAccount、Password、验证码
用LoginAccount,获得AdminStruct,成功就更新 tokenCreatTime
成功则进入首页 成功则进入首页
成功回:token,Name, 菜单按钮权限,首页展示内容(后面做统计内容,现在先全为空) 成功回:token,Name, 菜单按钮权限,首页展示内容(后面做统计内容,现在先全为空) AdminStruct RoleAuthStruct
2.
二、用户小程序接口
1. 登录:获取用户code->appid+appsecret+code获取session_key+openid等,生成token
2. 2.
\ No newline at end of file
package api package web
import ( import (
"dc_golang_server_1/config" "dc_golang_server_1/config"
"dc_golang_server_1/logger" "dc_golang_server_1/logger"
"dc_golang_server_1/middleware"
"fmt" "fmt"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
...@@ -12,11 +11,11 @@ func InitRouter() { //*gin.Engine{ ...@@ -12,11 +11,11 @@ func InitRouter() { //*gin.Engine{
gin.SetMode(config.HttpServerMode) gin.SetMode(config.HttpServerMode)
r := gin.New() r := gin.New()
r.Use(logger.HttpGinLog(), gin.Recovery()) r.Use(logger.HttpGinLog(), gin.Recovery())
r.Use(middleware.Cors()) //全局跨域 局部跨域的话在路由组里面去添加 r.Use(Cors()) //全局跨域 局部跨域的话在路由组里面去添加
r.Use(middleware.JwtToken()) //jwt 还是在对应需要token的路由组添加 r.Use(JwtToken()) //jwt 还是在对应需要token的路由组添加
user := r.Group("user/") user := r.Group("user/")
user.Use(middleware.JwtToken()) user.Use(JwtToken())
{ // 需要token的 { // 需要token的
//user.GET("users",GetUsers) //user.GET("users",GetUsers)
} }
...@@ -30,7 +29,7 @@ func InitRouter() { //*gin.Engine{ ...@@ -30,7 +29,7 @@ func InitRouter() { //*gin.Engine{
// 基础数据 // 基础数据
// 区域 // 区域
//router := r.Group("api/") //router := r.Group("web/")
{ {
//router.POST() //router.POST()
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment