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

海口建设企业网站网站建设乐云seo

海口建设企业网站,网站建设乐云seo,php网站编程,公司建设网站需要什么条件文章目录 使用 JWT 进行身份校验jwt知识点补充认识JWTTOKEN是什么jwt的使用场景jwt的组成headerpayloadsignature 下载依赖包编写 jwt 工具包jwt中间件编写如何获取token 编写获取token的Apimodels逻辑编写路由逻辑编写修改路由逻辑 验证token将中间件接入Gin功能验证模块 续接… 文章目录 使用 JWT 进行身份校验jwt知识点补充认识JWTTOKEN是什么jwt的使用场景jwt的组成headerpayloadsignature 下载依赖包编写 jwt 工具包jwt中间件编写如何获取token 编写获取token的Apimodels逻辑编写路由逻辑编写修改路由逻辑 验证token将中间件接入Gin功能验证模块 续接上部分 使用 JWT 进行身份校验 在前面几节中我们已经基本的完成了 API’s 的编写但是还存在一些非常严重的问题例如我们现在的API是可以随意调用的这显然还不安全全在本文中我们通过 jwt-go GoDoc的方式来简单解决这个问题。 jwt知识点补充 jwt官网 认识JWT JSON Web TokenJWT是一个开放标准RFC 7519它定义了一种紧凑和自包含的方式用于在各方之间作为JSON对象安全地传输信息。 作为标准它没有提供技术实现但是大部分的语言平台都有按照它规定的内容提供了自己的技术实现所以实际在用的时候只要根据自己当前项目的技术平台到官网上选用合适的实现库即可。 TOKEN是什么 Token其实就是服务端生成的一串加密字符串、以作客户端进行请求的一个“令牌” jwt的使用场景 以下是JWT两种使用场景 授权这是使用 JWT 的最常见的使用场景。用户登录后每个后续请求都将包含 JWT允许用户访问使用该令牌允许的路由、服务和资源。单点登录是当今广泛使用 JWT 的一项功能因为它的开销很小并且能够跨不同域轻松使用。 信息交换JWT是在各方之间安全传输信息的比较便捷的方式。由于 JWT 可以签名例如使用公钥/私钥对因此可以确定发送者是否是在您的授权范围之内。并且由于签名是使用标头和有效负载计算的因此还可以验证内容是否未被篡改。 jwt的组成 这是一个JWT的token串 eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c其实这一串是经过加密之后的密文字符串中间通过.来分割。每个.之前的字符串分别表示JWT的三个组成部分Header、Payload、Signature。 header Header的主要作用是用来标识,通常是两部分组成 typtype 的简写令牌类型也就是JWT。 algAlgorithm 的简写加密签名算法。一般使用HS256jwt官网提供了12种的加密算法 然后通过base64编码将明文编码,防止在传输过程中能直接一眼看出明文并符合多种传输协议 payload 也称为JWT claims payload用来承载要传递的数据它的json结构实际上是对JWT要传递的数据的一组声明这些声明被JWT标准称为claims它的一个“属性值对”其实就是一个claim每一个claim的都代表特定的含义和作用 claims有三类 保留claims主要包括iss发行者、exp过期时间、sub主题、aud用户等。 keyname说明iss发送者标识颁发 JWT 的发送主体sub主题标识 JWT 的主题aud接收者标识 JWT 所针对的接收者。每个在处理 JWT 的主体都必须使用受众声明中的值来标识自己。如果处理的主体在存在此声明时未将自己标识为声明中的值则必须拒绝 JWTexp到期时间标识不得接受 JWT 进行处理的过期时间。该值必须是日期类型而且是1970-01-01 000000Z 之后的日期秒。nbfjwt的开始处理的时间标识 JWT 开始接受处理的时间。该值必须是日期。iatjwt发出的时间标识 JWT 的发出的时间。该值必须是日期。jtijwt id令牌的区分大小写的唯一标识符即使在不同的颁发者之间也是如此。 保留claim为jwt标准中规定的claim验证方式已经定义好 公共claims定义新创的信息比如用户信息和其他重要信息。(使用较少)私有claims用于发布者和消费者都同意以私有的方式使用的信息。 明文实例 {sub: 12344321,name: Mars酱, // 私有claimsiat: 1516239022 }base64加密后 eyJzdWIiOiIxMjM0NDMyMSIsIm5hbWUiOiJNYXJz6YWxIiwiaWF0IjoxNTE2MjM5MDIyfQsignature Signature 部分是对Header和Payload两部分的签名作用是防止 JWT 被篡改。这个部分的生成规则主要是是公式伪代码是 Header中定义的签名算法alg(base64编码(header) . base64编码(payload),secret//在服务端加密使用的密钥 )JWT如果从字面上理解感觉是基于JSON格式用于网络传输的令牌。实际上JWT是一种紧凑的Claims声明格式常见的场景如HTTP授权请求头参数和URI查询参数。JWT会把Claims转换成JSON格式而这个JSON内容将会应用为JWS结构的有效载荷或者应用为JWE结构的加密处理后的原始字符串通过消息认证码Message Authentication Code或者简称MAC和/或者加密操作对Claims进行数字签名或者完整性保护。 下载依赖包 go get -u github.com/dgrijalva/jwt-go编写 jwt 工具包 我们需要编写一个jwt的工具包我们在pkg下的util目录新建jwt.go写入文件内容: package utilimport (timejwt github.com/dgrijalva/jwt-gogithub.com/kingsill/gin-example/pkg/setting )// 加载配置文件中设置的密钥 var jwtSecret []byte(setting.JwtSecret)// Claims 定义claims结构体 type Claims struct {Username string json:usernamePassword string json:passwordjwt.StandardClaims }func GenerateToken(username, password string) (string, error) {nowTime : time.Now()expireTime : nowTime.Add(3 * time.Hour)//创建 CustomClaims 结构体用来封装 jwt 信息claims : Claims{username,password,jwt.StandardClaims{ExpiresAt: expireTime.Unix(),Issuer: gin-blog,},}//创建 header和payload部分tokenClaims : jwt.NewWithClaims(jwt.SigningMethodHS256, claims)//得到完整的token字符串这里为加入签名signature部分token, err : tokenClaims.SignedString(jwtSecret)return token, err }func ParseToken(token string) (*Claims, error) {//解码过程tokenClaims, err : jwt.ParseWithClaims(token, Claims{}, func(token *jwt.Token) (interface{}, error) {return jwtSecret, nil})//验证是否时间过期if tokenClaims ! nil {if claims, ok : tokenClaims.Claims.(*Claims); ok tokenClaims.Valid {return claims, nil}}return nil, err } 在这个工具包我们涉及到: NewWithClaims(method SigningMethod, claims Claims)method对应着SigningMethodHMAC struct{}其包含SigningMethodHS256、SigningMethodHS384、SigningMethodHS512三种crypto.Hash方案func (t *Token) SignedString(key interface{}) 该方法内部生成签名字符串再用于获取完整、已签名的tokenfunc (p *Parser) ParseWithClaims 用于解析鉴权的声明方法内部主要是具体的解码和校验的过程最终返回*Tokenfunc (m MapClaims) Valid() 验证基于时间的声明exp, iat, nbf注意如果没有任何声明在令牌中仍然会被认为是有效的。并且对于时区偏差没有计算方法 jwt中间件编写 中间件相关知识 自定义中间件 有了jwt工具包接下来我们要编写要用于Gin的中间件我们在middleware下新建jwt目录新建jwt.go文件写入内容 package jwtimport (net/httptimegithub.com/gin-gonic/gingithub.com/kingsill/gin-example/pkg/egithub.com/kingsill/gin-example/pkg/util )// 自定义中间件 func JWT() gin.HandlerFunc {//返回.context函数return func(c *gin.Context) {var code intvar data interface{}//默认是正确状态code e.SUCCESS//参数查询url中token关键字token : c.Query(token)//如果为空则进行相关提示if token {code e.INVALID_PARAMS} else { //如果右token进行token的解析claims, err : util.ParseToken(token)if err ! nil { //如果解析出错相关提示code e.ERROR_AUTH_CHECK_TOKEN_FAIL} else if time.Now().Unix() claims.ExpiresAt { //如果解析出来token已过期则也有相关提示code e.ERROR_AUTH_CHECK_TOKEN_TIMEOUT}}//后续处理如果之前步骤有错误进行一下操作if code ! e.SUCCESS {c.JSON(http.StatusUnauthorized, gin.H{code: code,msg: e.GetMsg(code),data: data,})//放弃后续中间件的执行即如果有错后续中间件都不执行c.Abort()return}//如果没错放行 next前为请求中间件next后为相应中间件c.Next()} }如何获取token 编写获取token的Api 那么我们如何调用它呢我们还要获取Token呢 models逻辑编写 在models下新建auth.go文件写入内容 package models// jwt验证的 数据库相关操作// Auth 用户对应的struct模型 type Auth struct {ID int gorm:primary_key json:idUsername string json:usernamePassword string json:password }// CheckAuth 根据用户名和密码查询用户是否存在 func CheckAuth(username, password string) bool {var auth Authdb.Select(id).Where(Auth{Username: username, Password: password}).First(auth)if auth.ID 0 {return true}return false }} 路由逻辑编写 在routers下的api目录新建auth.go文件写入内容 package v1import (lognet/httpgithub.com/astaxie/beego/validationgithub.com/gin-gonic/gingithub.com/kingsill/gin-example/modelsgithub.com/kingsill/gin-example/pkg/egithub.com/kingsill/gin-example/pkg/util )// 定义我们验证用户所需的信息同时定义valid验证的预定信息即一定要有并且最大字符数为50 type auth struct {Username string valid:Required; MaxSize(50)Password string valid:Required; MaxSize(50) }func GetAuth(c *gin.Context) {//参数查询模式获取用户名和密码username : c.Query(username)password : c.Query(password)//通过设立结构体验证的valid验证即所需并且最大为50个字符valid : validation.Validation{}a : auth{Username: username, Password: password}ok, _ : valid.Valid(a)//建立存储信息的map key类型为stringval类型为任意值data : make(map[string]interface{})//设置默认code为参数错误code : e.INVALID_PARAMS//通过前序验证继续通过数据库进行验证if ok {//通过数据库进行验证isExist : models.CheckAuth(username, password)//如果通过数据库验证if isExist {//创建token令牌token, err : util.GenerateToken(username, password)if err ! nil { //如果生成令牌失败code e.ERROR_AUTH_TOKEN} else { //生成token成功进行存储data[token] tokencode e.SUCCESS}} else { //没通过数据库验证code e.ERROR_AUTH}} else { //没通过前序验证for _, err : range valid.Errors {log.Println(err.Key, err.Message)}}//json相应c.JSON(http.StatusOK, gin.H{code: code,msg: e.GetMsg(code),data: data,}) }修改路由逻辑 我们打开routers目录下的router.go文件修改文件内容新增获取 token 的方法 增添一句 r.GET(/auth, api.GetAuth)放在路由组之外 func InitRouter() *gin.Engine { r : gin.New()r.Use(gin.Logger())r.Use(gin.Recovery())gin.SetMode(setting.RunMode)r.GET(/auth, api.GetAuth)//------------------------apiv1 : r.Group(/api/v1) { ... }return r }验证token 获取token的 API 方法就到这里啦让我们来测试下是否可以正常使用吧 重启服务后用GET方式访问http://127.0.0.1:8000/auth?usernametestpasswordtest123456 查看返回值是否正确 {code: 200,data: {token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InRlc3QiLCJwYXNzd29yZCI6InRlc3QxMjM0NTYiLCJleHAiOjE3MDUzMzk2MzUsImlzcyI6Imdpbi1ibG9nIn0.4zblfic9MdOvrg4TF9Li8nfw3FSBq3rGgKqnJnDFXYY},msg: ok }我们有了token的 API也调用成功了 将中间件接入Gin 修改路由分组模块语句apiv1 : r.Group(/api/v1).Use(jwt.JWT())将jwt验证加入全局路由 ...apiv1 : r.Group(/api/v1) apiv1.Use(jwt.JWT()) { ... } ...当前目录结构 go-gin-example/ ├── conf │ └── app.ini ├── main.go ├── middleware │ └── jwt │ └── jwt.go ├── models │ ├── article.go │ ├── auth.go │ ├── models.go │ └── tag.go ├── pkg │ ├── e │ │ ├── code.go │ │ └── msg.go │ ├── setting │ │ └── setting.go │ └── util │ ├── jwt.go │ └── pagination.go ├── routers │ ├── api │ │ ├── auth.go │ │ └── v1 │ │ ├── article.go │ │ └── tag.go │ └── router.go ├── runtime到这里我们的JWT编写就完成啦 功能验证模块 我们来测试一下再次访问 http://127.0.0.1:8000/api/v1/articleshttp://127.0.0.1:8000/api/v1/articles?token23131 正确的反馈应该是 {code: 400,data: null,msg: 请求参数错误 }{code: 20001,data: null,msg: Token鉴权失败 } 我们需要访问http://127.0.0.1:8000/auth?usernametestpasswordtest123456 得到token 再用包含token的 URL 参数去访问我们的应用 API 这里的问题即为创建的token还需要自己复制粘贴不能自动取用等 访问http://127.0.0.1:8000/api/v1/articles?tokeneyJhbGci... 检查接口返回值 {code: 200,data: {lists: [],total: 0},msg: ok }验证正确文章列表取决于数据库内容
http://www.zqtcl.cn/news/154981/

相关文章:

  • 做商城网站哪里高端大气网站案例
  • 网站做项目网站设计公司深
  • 学校做网站及费用建设网站有何要求
  • 河北邢台移动网站建设宁波网站开发公司电话
  • 免费建立个人网站申请seo搜索引擎优化推广
  • 如何拷贝服务器里面网站做备份金融网站怎么做的
  • 什么网站做的比较好网上投资网站建设
  • 公司网站运营方案策划办网站怎么赚钱
  • 贾汪区建设局网站设计接单兼职网站
  • 东莞商城网站建设哪家便宜wordpress 插件路径
  • 网站服务器 安全快递系统专注快递企业网站开发
  • 旅游网站平台建设的方案深圳移动官网网站建设
  • 如何建设企业人力资源网站网站建设和网络优化的区别
  • 辽宁网站设计影响网站用户体验
  • cms网站如何修改黄山建设网站
  • 宾爵手表官方网站小熊源码网
  • 荥阳网站建设网站建设取得了
  • 江苏省住房和城乡建设厅 官方网站wordpress点击下载
  • 找家里做的工作上哪个网站公司取名三个字推荐
  • 购物网站建设源码wordpress 多多进宝
  • 重庆定制网站建设地址晋安福州网站建设
  • 360建网站了解深圳网站页面设计
  • 哪些网站首页做的好蛋糕网站内容规划
  • 富阳市网站息壤服务器网站打不开
  • 中文建站模板客户做网站嫌贵了
  • 做网站用jquery做网站都有哪些费用
  • 网站知识安卓studio制作一个简单app
  • 一个购物网站开发语言外贸企业
  • 给一个装修公司怎么做网站做网站打开图片慢
  • 互联网三网合一网站建设银川网站建站公司