本篇文章主要介绍Gin框架实现token前端登录验证的流程,前端框架采用Vue3,后端采用Go,技术用到的有jwt
"github.com/dgrijalva/jwt-go"
我们需要导入以上的jwt的包
go get -u github.com/dgrijalva/jwt-go
运行上述代码
之后我们需要在model包里面新建一个数据流,后面我们会用到这个
type Claims struct {
Username string `json:"username"`
Password string `json:"password"`
jwt.StandardClaims
}
之后在主函数中声明一个创造Token的函数
func GenerateToken(username, password string) (string, error) {
//设置token有效时间
nowTime := time.Now()
expireTime := nowTime.Add(3 * time.Hour)
claims := model.Claims{
Username: username,
Password: password,
StandardClaims: jwt.StandardClaims{
// 过期时间
ExpiresAt: expireTime.Unix(),
// 指定token发行人
Issuer: "gin-blog",
},
}
tokenClaims := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
//该方法内部生成签名字符串,再用于获取完整、已签名的token
key := "sahjdjsgaudsiudhuywge"
var keys []byte = []byte(key)
token, err := tokenClaims.SignedString(keys)
return token, err
}
上述的key我随便写的
值得注意的是我前端采用的是Vue,所以用户信息之类的都在Request Payload中,所以Go读取这个区域的数据代码如下
ctx.Request.Body.Read
主要是用于读取流数据的函数
ioutil.NopCloser
就是将一个不带 Close 的 Reader 封装成 ReadCloser,我们在操作req *http.Request
和response *http.Response
的时候,有时候需要读取Body,但是读了之后Body里面就被清空了,因此我们需要将读取的内容又重新赋值给Body。它的类型为io.ReadCloser
json.Unmarshal
将数据结构转化为json字符串
json.marshal
将json字符串转化为数据结构
buf := make([]byte, 1024)
n, _ := ctx.Request.Body.Read(buf)
ctx.Request.Body = ioutil.NopCloser(bytes.NewReader(buf[:n]))
j := buf[0:n]
fmt.Println("body:", string(j)) //获取到post传递过来的数据
admin_admin := Info{}
err := json.Unmarshal(j, &admin_admin) //结构体字段变量名字必须大写,不然无法转码
fmt.Println(admin_admin.Username)
if err != nil {
fmt.Println(err)
return
}
func ParseToken(token string) (*model.Claims, error) {
//用于解析鉴权的声明,方法内部主要是具体的解码和校验的过程,最终返回*Token
tokenClaims, err := jwt.ParseWithClaims(token, &model.Claims{}, func(token *jwt.Token) (interface{}, error) {
return keys, nil
})
if tokenClaims != nil {
// 从tokenClaims中获取到Claims对象,并使用断言,将该对象转换为我们自己定义的Claims
// 要传入指针,项目中结构体都是用指针传递,节省空间。
if claims, ok := tokenClaims.Claims.(*model.Claims); ok && tokenClaims.Valid {
return claims, nil
}
}
return nil, err
}
总结:基于Go的token验证机制如上述