zoukankan      html  css  js  c++  java
  • 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
    }
  • 相关阅读:
    swagger本地环境搭建
    上传图片报错
    接口自动化测试---环境搭建
    IDEA 运行程序提交hdfs时,报错
    hadoop2.60集群搭建
    查找排除当前最大、最小salary之后的员工的平均工资avg_salary。
    按照salary的累计和running_total,其中running_total为前两个员工的salary累计和
    CSS补充
    BFC(块级格式化上下文)
    CSS精灵技术
  • 原文地址:https://www.cnblogs.com/arvin-an/p/14665609.html
Copyright © 2011-2022 走看看