golang goframe jwt token

// 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
}
原文地址:https://www.cnblogs.com/arvin-an/p/14665609.html