// token key
var tokenKey = "5Gir3eXHbSwFWxyNaZfbulN0GdiObmvp"
// 登录
func Login(r *ghttp.Request) (interface{}, error) {
username := r.GetString("username")//用户名
u, e := g.DB().Table("*****").Where("username=?", g.Slice{username}).Fields("id,username,password").One()//数据库查询
if e != nil {
return nil, e
}
if u.IsEmpty() {
return nil, errors.New("账号或密码错误")
}
// 密码验证
if !validatePassword(r.GetString("password"), gconv.String(u["password"])) {
return nil, errors.New("账号或密码错误")
}
// 生成 access token
accessToken, e := CreateToken(&u, false)
if e != nil {
return nil, e
}
// 生成refresh token
refreshToken, e := CreateToken(&u, true)
if e != nil {
return nil, e
}
return g.Map{
"access_token": accessToken["token"],
"access_token_expire_at": accessToken["exp"],
"refresh_token": refreshToken["token"],
"refresh_token_expire_at": refreshToken["exp"],
}, nil
}
// 使用refresh token 刷新 access token 和 refresh token
func RefreshToken(r *ghttp.Request) (interface{}, error) {
refreshTokenString := r.GetString("refresh_token") // 获取刷新token
claims, err := ParseToken(refreshTokenString) // 解析token
if err != nil {
return nil, err
}
claimsMap := gconv.Map(claims) // token解析后的数据
u, _ := g.DB().Table("*****").Where("id=?", g.Slice{claimsMap["id"]}).Fields("id,username,password").One()
// 生成access_token
accessToken, e := CreateToken(&u, false)
if e != nil {
return nil, e
}
// 生成refresh_token
refreshToken, e := CreateToken(&u, true)
if e != nil {
return nil, e
}
return g.Map{
"access_token": accessToken["token"],
"access_token_expire_at": accessToken["exp"],
"refresh_token": refreshToken["token"],
"refresh_token_expire_at": refreshToken["exp"],
}, nil
}
// 使用access token 获取 refresh token
func ReToken(r *ghttp.Request) (interface{}, error) {
tokenString := GetHeaderToken(r)
fmt.Println(tokenString)
claims, err := ParseToken(tokenString)
if err != nil {
return nil, err
}
glog.Line().Println(claims)
claimsMap := gconv.Map(claims)
u, _ := g.DB().Table("*****").Where("id=?", g.Slice{claimsMap["id"]}).Fields("id,username,password").One()
return CreateToken(&u, true)
}
// 获取header token
func GetHeaderToken(r *ghttp.Request) string {
headerAuthorization := r.Header.Get("Authorization")
if headerAuthorization != "" {
parts := strings.SplitN(headerAuthorization, " ", 2)
if !(len(parts) == 2 && parts[0] == "Bearer") {
return ""
}
return parts[1]
}
return ""
}
// 创建token
func CreateToken(u *gdb.Record, isRe bool) (map[string]interface{}, error) {
user := gconv.Map(u)
expireAt := time.Now().Add(time.Hour).Unix()
<!--如果是生成刷新token 加长时间-->
if isRe {
expireAt = time.Now().Add(time.Hour * 1000).Unix()
}
claims := jwt.MapClaims{
"id": gconv.String(user["id"]),
"username": gconv.String(user["username"]),
"exp": expireAt,
"iat": xtime.GetNow().Unix(),
}
glog.Line().Println(claims)
tokenClaims := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
token, err := tokenClaims.SignedString([]byte(tokenKey))
return g.Map{
"token": token,
"exp": expireAt,
}, err
}
type Claims struct {
Id string `json:"id"`
Username string `json:"username"`
jwt.StandardClaims
}
// 解析token
func ParseToken(token string) (interface{}, error) {
tokenClaims, err := jwt.ParseWithClaims(token, &Claims{}, func(token *jwt.Token) (interface{}, error) {
return []byte(tokenKey), nil
})
if err != nil {
fmt.Println(err)
return nil, errors.New("token 解析失败1")
}
claims, ok := tokenClaims.Claims.(*Claims)
fmt.Println(claims)
if !ok {
return nil, errors.New("token 解析失败2")
}
if !tokenClaims.Valid {
return nil, errors.New("token 已过期")
}
//if claims, ok := tokenClaims.Claims.(*Claims); ok && tokenClaims.Valid {
// return claims, nil
//}
return claims, err
}
// 验证密码
func validatePassword(passwordString, hashedPasswordString string) bool {
inputPassword := []byte(passwordString)
hashedPassword := []byte(hashedPasswordString)
e := bcrypt.CompareHashAndPassword(hashedPassword, inputPassword)
if e != nil {
return false
}
return true
}