1.准备工作
1.官方网址:jwt package - github.com/dgrijalva/jwt-go - Go Packages
2.安装jwt包
go get github.com/dgrijalva/jwt-go
安装完成:
3.在common目录下新建一个jwt.go文件
4.post请求get请求的区别
POST请求和GET请求是两种常见的HTTP请求方法,它们有以下几个区别:
-
GET请求会把请求参数拼接到URL后面,而POST请求则是将请求参数放在请求体中发送。因此,GET请求的请求参数会暴露在URL中,而POST请求的请求参数不会。
-
GET请求通常用于请求资源,而POST请求通常用于提交数据。GET请求会向服务器请求一个资源(如HTML页面或者图片),而POST请求则是向服务器提交表单数据或者上传文件等操作。
-
GET请求的请求参数长度受到URL长度限制,通常不能超过2048个字符。而POST请求的参数长度通常没有严格限制,可以传输更大的数据量。
-
GET请求是幂等的,也就是说,多次相同的GET请求返回的结果应该是一样的。而POST请求不是幂等的,即使发送相同的请求数据,每次响应可能都不同。
总的来说,GET请求适合用于查询数据,POST请求适合于提交数据。在实际开发中,需要根据具体场景选择合适的请求方法。
2.代码实现
1.jwt.go
package common
import (
"ginEssential/model"
"github.com/dgrijalva/jwt-go"
"time"
)
// 定义一个jwt加密的密钥
var jwtKey = []byte("a_secret_crect")
// 定义token的Claims
type Claims struct {
UserId uint
jwt.StandardClaims
}
// 登录成功之后就调用这个方法来释放token
func ReleaseToken(user model.User) (string, error) {
//定义token的过期时间:7天
expirationTime := time.Now().Add(7 * 24 * time.Hour)
claims := &Claims{
UserId: user.ID,
StandardClaims: jwt.StandardClaims{
ExpiresAt: expirationTime.Unix(),
IssuedAt: time.Now().Unix(), //token发放的时间
Issuer: "admin", //发放人
Subject: "user token", //主题
},
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
//使用jwt密钥来生成token
tokenString, err := token.SignedString(jwtKey)
if err != nil {
return "", err
}
return tokenString, nil
}
修改Usercontroller.go的部分代码
//发放token
token, err := common.ReleaseToken(user)
if err != nil {
ctx.JSON(http.StatusInternalServerError, gin.H{"code": 500, "msg": "系统异常"})
log.Printf("token generate error :%v ", err)
return
}
生成的token
token的组成:
一共由三部分组成:
1.协议头(header):token使用的加密协议
2.荷载:储存的是token发放时间、发放人、主题等信息
3.第三部分:前面两部分+key进行hash的一个值
使用base64来解密token信息
echo eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 | base64 -D
2.写认证中间件
1.创建一个新的文件夹:middleware
创建一个新的go文件:AuthMiddleware.go
2.在jwt.go里面新定义一个函数用来解析token
// 定义一个函数用来解析token
func ParseToken(tokenString string) (*jwt.Token, *Claims, error) {
claims := &Claims{}
token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) {
return jwtKey, nil
})
return token, claims, err
}
3.创建一个用户信息的路由
完成这个接口
接下来用中间件来保护用户信息接口
效果展示
4.存在的问题以及解决方法
问题:返回前端是所有数据,应该选择部分数据返回
解决:新建一个包:dto,创建一个go文件,里面选择要返回的数据
package dto
import "ginEssential/model"
// 定义一个UserDto结构体
type UserDto struct {
//选择返回给前端哪些数据
Name string `json:"name"`
Telephone string `json:"telephone"`
}
// 定义一个转换的函数
func ToUserDto(user model.User) UserDto {
return UserDto{
Name: user.Name,
Telephone: user.Telephone,
}
}
在UserController里面修改返回的值
结果
3.封装http返回
1.新建包response以及同名的go文件
2.代码
package response
import (
"github.com/gin-gonic/gin"
"net/http"
)
func Response(ctx *gin.Context, httpStatus int, code int, data gin.H, msg string) {
ctx.JSON(httpStatus, gin.H{"code": code, "data": data, "msg": msg})
}
// 定义两个常用的返回
// 成功
func Success(ctx *gin.Context, data gin.H, msg string) {
Response(ctx, http.StatusOK, 200, data, msg)
}
// 失败
func Fail(ctx *gin.Context, msg string, data gin.H) {
//失败也是返回200,然后返回400的状态码
Response(ctx, http.StatusOK, 400, data, msg)
}
3.修改之前的代码,使其规范化
进行一个替换