当前位置: 首页 > news >正文

山东省住房和城乡建设厅电话号码成都seo

山东省住房和城乡建设厅电话号码,成都seo,郴州网站制作公司有哪些,wordpress分页diam文章目录 一:介绍二:Gin JWT 后台1. Claims 定义2. 创建和解析Token3. Gin中间件编写4. 辅助函数 三:Ant Design Pro JWT认证四:Gin中间件和使用示范 一:介绍 JWT现在比较流行的认证方式,微服务中使用特别…

文章目录

  • 一:介绍
  • 二:Gin JWT 后台
    • 1. `Claims `定义
    • 2. 创建和解析Token
    • 3. Gin中间件编写
    • 4. 辅助函数
  • 三:Ant Design Pro JWT认证
  • 四:Gin中间件和使用示范

一:介绍

  • JWT现在比较流行的认证方式,微服务中使用特别常见。
  • JWT标准格式

在HTTP请求添加名为Authorization的header,形式如下: (token前面Bearer 是标准前缀字符串)
Authorization: Bearer

  • Go JWT 结构体Claims,可以理解为需要保存的信息,加密后会存储在token中,解密后会从token自动解析出来

配合ant design pro前端实现需要解决以下问题:

  • JWT TOKEN需要存储哪些字段以及定义,如何创建和解析
  • 前端发送请求时如何自动添加JWT认证信息
  • JWT TOKEN过期后,前后端如何配合自动刷新

二:Gin JWT 后台

使用库github.com/golang-jwt/jwt/v5

1. Claims 定义

jwt.RegisteredClaimsgithub.com/golang-jwt/jwt/v5预设的标准claims,后面用到其ExpiresAt过期时间字段,UserClaims 为自定义存储的字段,最终加密到token中的是jwtClaims结构

type UserClaims struct {
// 可以添加字段存储其他信息UserID   uint   `json:"userId"`RoleID   uint   `json:"roleId"`UserName string `json:"username"`
}type jwtClaims struct {UserClaimsjwt.RegisteredClaims
}

2. 创建和解析Token

expireHoursrefreshHours分别是设置过期时间,以及距离过期时间多久返回新token,后续在gin中间件中判断,方式是在Header中返回x-refresh-tokennewToken

type JWT struct {secret       []byteexpireHours  time.TimerefreshHours time.Duration
}// j := NewJWT("密钥", 2, 1)
// token过期时间是2小时, 距离过期时间还有1小时时在`Header`中返回`x-refresh-token`:`newToken`
func NewJWT(secret string, expireHours int, refreshHours int) *JWT {return &JWT{secret:       []byte(secret),expireHours:  time.Now().Add(time.Duration(expireHours) * time.Hour),refreshHours: time.Hour * time.Duration(refreshHours),}
}func (j *JWT) CreateToken(u UserClaims) (string, error) {token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwtClaims{UserClaims: u,RegisteredClaims: jwt.RegisteredClaims{ExpiresAt: jwt.NewNumericDate(j.expireHours),IssuedAt:  jwt.NewNumericDate(time.Now()),},})return token.SignedString(j.secret)
}func (j *JWT) ParseToken(tokenString string) (*jwtClaims, error) {token, err := jwt.ParseWithClaims(tokenString, &jwtClaims{}, func(token *jwt.Token) (interface{}, error) {return j.secret, nil})if err != nil {return nil, err}if claims, ok := token.Claims.(*jwtClaims); ok && token.Valid {return claims, nil} else {return nil, errors.New("Token无效")}
}

3. Gin中间件编写

type BaseResponse struct {Success      bool   `json:"success"`Data         any    `json:"data"`Message      string `json:"message"`ErrorMessage string `json:"errorMessage"`
}func OkWithData(c *gin.Context, data any) {c.JSON(200, BaseResponse{Success: true, Data: data})
}func OkWithMsg(c *gin.Context, msg string) {c.JSON(200, BaseResponse{Success: true, Message: msg})
}func Fail(c *gin.Context, errMsg string) {c.JSON(200, BaseResponse{Success: false, ErrorMessage: errMsg})
}
// 使用如下:
// // token过期时间是2小时, 距离过期时间还有1小时时在`Header`中返回`x-refresh-token`:`newToken`
// j := NewJWT("密钥", 2, 1)
// r.USE(JWTAuth(j))
func JWTAuth(j *JWT) gin.HandlerFunc {return func(c *gin.Context) {token := c.Request.Header.Get("Authorization")token = strings.TrimPrefix(token, "Bearer ")claims, err := j.ParseToken(token)if err != nil {response.Fail(c, "Token错误: "+err.Error())c.Abort()return}if time.Since(claims.ExpiresAt.Local()) < j.refreshHours {newToken, err := j.CreateToken(claims.UserClaims)if err != nil {response.Fail(c, "Token刷新错误: "+err.Error())c.Abort()return}c.Header("x-refresh-token", newToken)}c.Set("claims", claims)c.Next()}}

4. 辅助函数

gin中直接调用该函数可以方便的获取到存储的机构体信息

func GetUserToken(c *gin.Context) *UserClaims {claims, _ := c.Get("claims")if claims == nil {return &UserClaims{}}return &claims.(*jwtClaims).UserClaims
}

三:Ant Design Pro JWT认证

处理登录请求后返回jwt token使用localStorage.setItem('jwt', token)存储起来
app.tsx的文件request定义中添加拦截器,实现方法:

  • 请求前,在header中添加头·Authorization·: 'Bearer ’ + localStorage.getItem(‘jwt’) || ‘’
  • 请求后,检测header中是否存在x-refresh-token,存在的话更新token,目的是防止token过期自动刷新
    实现如下:
function setToken(token: string) {localStorage.setItem('jwt', token);
}function getToken(): string {return localStorage.getItem('jwt') || '';
}export const request = {...errorConfig,// 请求前拦截器requestInterceptors: [(url: string, options: RequestConfig) => {const authHeader = { Authorization: 'Bearer ' + getToken() };return {url: `${url}`,options: { ...options, interceptors: true, headers: authHeader },};},],// 请求后拦截器responseInterceptors: [(response: Response, options: RequestConfig) => {if (response.headers.has('x-refresh-token')) {setToken(response.headers.get('x-refresh-token') || '');}return response;},],
};

四:Gin中间件和使用示范

jwt_middleware.go

package middlewareimport ("errors""strings""time""github.com/gin-gonic/gin""github.com/golang-jwt/jwt/v5"
)// 可以添加字段存储其他信息
type UserClaims struct {UserID   uint   `json:"userId"`RoleID   uint   `json:"roleId"`UserName string `json:"username"`
}type jwtClaims struct {UserClaimsjwt.RegisteredClaims
}type JWT struct {secret       []byteexpireHours  time.TimerefreshHours time.Duration
}// j := NewJWT("密钥", 2, 1)
// token过期时间是2小时, 距离过期时间还有1小时时在`Header`中返回`x-refresh-token`:`newToken`
func NewJWT(secret string, expireHours int, refreshHours int) *JWT {return &JWT{secret:       []byte(secret),expireHours:  time.Now().Add(time.Duration(expireHours) * time.Hour),refreshHours: time.Hour * time.Duration(refreshHours),}
}func (j *JWT) CreateToken(u UserClaims) (string, error) {token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwtClaims{UserClaims: u,RegisteredClaims: jwt.RegisteredClaims{ExpiresAt: jwt.NewNumericDate(j.expireHours),IssuedAt:  jwt.NewNumericDate(time.Now()),},})return token.SignedString(j.secret)
}func (j *JWT) ParseToken(tokenString string) (*jwtClaims, error) {token, err := jwt.ParseWithClaims(tokenString, &jwtClaims{}, func(token *jwt.Token) (interface{}, error) {return j.secret, nil})if err != nil {return nil, err}if claims, ok := token.Claims.(*jwtClaims); ok && token.Valid {return claims, nil} else {return nil, errors.New("Token无效")}
}// 使用如下:
// // token过期时间是2小时, 距离过期时间还有1小时时在`Header`中返回`x-refresh-token`:`newToken`
// j := NewJWT("密钥", 2, 1)
// r.USE(JWTAuth(j))
func JWTAuth(j *JWT) gin.HandlerFunc {return func(c *gin.Context) {token := c.Request.Header.Get("Authorization")token = strings.TrimPrefix(token, "Bearer ")claims, err := j.ParseToken(token)if err != nil {response.Fail(c, "Token错误: "+err.Error())c.Abort()return}if time.Since(claims.ExpiresAt.Local()) < j.refreshHours {newToken, err := j.CreateToken(claims.UserClaims)if err != nil {response.Fail(c, "Token刷新错误: "+err.Error())c.Abort()return}c.Header("x-refresh-token", newToken)}c.Set("claims", claims)c.Next()}}func GetUserToken(c *gin.Context) *UserClaims {claims, _ := c.Get("claims")if claims == nil {return &UserClaims{}}return &claims.(*jwtClaims).UserClaims
}type BaseResponse struct {Success      bool   `json:"success"`Data         any    `json:"data"`Message      string `json:"message"`ErrorMessage string `json:"errorMessage"`
}func OkWithData(c *gin.Context, data any) {c.JSON(200, BaseResponse{Success: true, Data: data})
}func OkWithMsg(c *gin.Context, msg string) {c.JSON(200, BaseResponse{Success: true, Message: msg})
}func Fail(c *gin.Context, errMsg string) {c.JSON(200, BaseResponse{Success: false, ErrorMessage: errMsg})
}

main.go

package middlewareimport ("fmt""github.com/gin-gonic/gin"
)func main() {j := NewJWT("密钥", 2, 1)r := gin.Default()r.POST("/login", func(ctx *gin.Context) {// 处理登录逻辑返回token, 前端需讲token存储到localstoragetoken, err := j.CreateToken(UserClaims{UserID: 1, RoleID: 1, UserName: "Leo"})if err != nil {response.Fail(ctx, err.Error())return}response.OkWithData(ctx, gin.H{"token": token})})auth := r.Group("/api")auth.Use(JWTAuth(j))auth.GET("/test", func(ctx *gin.Context) {u := GetUserToken(ctx)response.OkWithMsg(ctx, fmt.Sprintf("用户ID:%d角色ID:%d用户名:%s", u.UserID, u.RoleID, u.UserName))})
}
http://www.ds6.com.cn/news/108799.html

相关文章:

  • 梁山网站建设企业培训课程价格
  • 利用网站空间做代理2022年列入传销组织最新骗法
  • 建网站的英文企业宣传片制作
  • 聊城做网站的公司案例重大军事新闻
  • 做网站从哪里找货源推广资源网
  • 微信公众号模板哪里找seo 0xu
  • 怎么做网站自动响应百度上做推广怎么做
  • 777fj做最好的网站商品推广软文范例200字
  • 中学网站系统源码百度推广怎么做
  • 南京需要做网站的公司国内建站平台有哪些
  • 哪些网站使用vue做的狼雨seo网站
  • 球球是哪个公司开发的结构优化设计
  • wordpress安全监测西安网站seo技术厂家
  • 淮北网站建设关键词分布中对seo有危害的
  • 阿里云网站建设套餐怎么查询最新网站
  • 东莞seo网站建设公司小广告设计
  • 信息门户网站制作2024年重大新闻摘抄
  • 分类网站怎么做项目seo软件哪个好
  • wordpress做垃圾站淘宝推广平台有哪些
  • 东莞公司网站价格贵阳网络推广外包
  • 东莞网站推广电话怎么制作网站教程步骤
  • 东营网络科技有限公司上海搜索引擎优化1
  • 网站做程序刚刚济南发通知
  • 山东外贸国际网站建设福州模板建站哪家好
  • 网站的底部导航栏怎么做百度推广入口
  • 学术推广北京seo站内优化
  • 便宜自适应网站建设厂家欧洲站fba
  • 做的比较好的法律实务培训网站常见的网络直接营销有哪些
  • 做网站的框架结构seo优化易下拉霸屏
  • 企业可以在哪些网站做免费宣传长春seo结算