文章目录

  • 在Go IRIS中使用JWT
    • 1. 跨域认证
    • 2. 关于JWT
    • 3. JWT 工作原理
    • 4. 在Iris中使用 JWT

在Go IRIS中使用JWT

1. 跨域认证

互联网服务离不开用户认证,一种认证方式是:

1、用户向服务器发送用户名和密码。

2、服务器验证通过后,在当前对话(session)里面保存相关数据,比如用户角色、登录时间等等。

3、服务器向用户返回一个 session_id,写入用户的 Cookie。

4、用户随后的每一次请求,都会通过 Cookie,将 session_id 传回服务器。

5、服务器收到 session_id,找到前期保存的数据,由此得知用户的身份。

这种模式的问题在于,扩展性(scaling)不好。单机当然没有问题,如果是服务器集群,或者是跨域的服务导向架构,就要求 session 数据共享,每台服务器都能够读取 session。

2. 关于JWT

JSON Web Token(JWT)是一个开放标准(RFC 7519),它定义了一种紧凑且独立的方式,可以在各方之间作为JSON对象安全地传输信息。 此信息可以通过数字签名进行验证和信任。JWT可以使用秘密(使用HMAC算法)或使用RSA或ECDSA的公钥/私钥对进行签名。

JWT 的原理是,服务器认证以后,生成一个 JSON 对象,发回给用户,就像下面这样。

{"name":    name, // 用户名"exp":      time.Now().Add(time.Hour * 2).Unix(), // 添加过期时间
}

以后,用户与服务端通信的时候,都要发回这个 JSON 对象。服务器完全只靠这个对象认定用户身份。为了防止用户篡改数据,服务器在生成这个对象的时候,会加上签名。

服务器就不保存任何 session 数据了,也就是说,服务器变成无状态了,从而比较容易实现扩展。

实际的 JWT 大概就像下面这样:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1NTk4MDMyODEsInBhc3N3b3JkIjoiMTIzMyIsInBob25lIjoiMTU5MDIwMTUwNDMifQ.NvKsiKh37pxmRH4inKb32EXT-XkSfIC96nEX7p1RLag

它是一个很长的字符串,中间用点(.)分隔成三个部分:Header.Payload.Signature

  • Header(头部):一个 JSON 对象,描述 JWT 的元数据,一般如下所示:
{"alg": "HS256","typ": "JWT"
}

alg属性表示签名的算法(algorithm),默认是 HMAC SHA256(写成 HS256);typ属性表示这个令牌(token)的类型(type),JWT 令牌统一写为JWT。最后,将上面的 JSON 对象使用 Base64URL 算法转成字符串。

  • Payload(负载):也是一个 JSON 对象,用来存放实际需要传递的数据

Payload示例

{"sub": "1234567890","name": "John Doe","admin": true
}
`

然后,Payload经过Base64Url编码,形成JSON Web Token的第二部分,数据虽然是不可串改,但是确实透明的

  • Signature(签名):对前两部分的签名,防止数据篡改;首先,需要指定一个密钥(secret)。这个密钥只有服务器才知道,不能泄露给用户。然后,使用 Header 里面指定的签名算法(默认是 HMAC SHA256),按照下面的公式产生签名。

例如,如果要使用HMAC SHA256算法,将按以下方式创建签名:

HMACSHA256(base64UrlEncode(header) + "." +base64UrlEncode(payload),secret)
`

签名用于验证消息在此过程中未被更改,并且,在使用私钥签名的令牌的情况下,它还可以验证JWT的发件人是否是它所声称的人

需要注意的是,使用签名TokenToken中包含的所有信息都会向用户或其他方公开,即使他们无法更改。这意味着您不应该在Token中放置秘密信息。

3. JWT 工作原理

在身份验证中,当用户使用其凭据成功登录时,将返回JSON Web Token。由于Token是凭证,因此必须非常小心以防止出现安全问题。 一般情况下,您不应该将令牌保留的时间超过要求。

每当用户想要访问受保护的路由或资源时,用户代理应该使用承载模式发送JWT,通常在Authorization Header中。Header的内容应如下所示:

Authorization: Bearer <token>

在某些情况下,这可以是无状态授权机制。服务器的受保护路由将在Authorization Header中检查有效的JWT,如果存在,则允许用户访问 受保护的资源。如果JWT包含必要的数据,则可以减少查询数据库以进行某些操作的需要,尽管可能并非总是如此。

如果在Authorization Header中发送Token,则跨域资源共享(CORS)将不会成为问题,因为它不使用cookie

使用过程:

  1. 应用程序或客户端向授权服务器请求授权。这是通过其中一个不同的授权流程执行的。例如,典型的OpenID Connect兼容Web应用程序 将使用授权代码流通过/oauth/authorize端点。
  2. 授予授权后,授权服务器会向应用程序返回访问Token
  3. 应用程序使用访问Token来访问受保护资源(如API)。

4. 在Iris中使用 JWT

在go中,开发者可以使用"github.com/dgrijalva/jwt-go" 很简单地使用JWT功能:

首先,终端输入下面的命令下载相关的包:

go get -u "github.com/dgrijalva/jwt-go"

之后,我们就可以直接import使用jwt包了:

import (jwt "github.com/dgrijalva/jwt-go""github.com/kataras/iris"
)

在之前的博客:Go iris 入门,里面提到了中间件的概念,JWT验证的方式也是一样的,我们可以自定义一个JWT 中间件来进行JWT验证:

下面的代码是一个自定义JWT中间件的简单例子,里面使用的密钥是My Secret,(因此在加密的时候需要使用同样的密钥),加密算法是HS256

jwtHandler := jwtmiddleware.New(jwtmiddleware.Config{//这个方法将验证jwt的tokenValidationKeyGetter: func(token *jwt.Token) (interface{}, error) {//自己加密的秘钥或者说盐值return []byte("My Secret"), nil},//设置后,中间件会验证令牌是否使用特定的签名算法进行签名//如果签名方法不是常量,则可以使用ValidationKeyGetter回调来实现其他检查//重要的是要避免此处的安全问题:https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries///加密的方式SigningMethod: jwt.SigningMethodHS256,//验证未通过错误处理方式//ErrorHandler: func(context.Context, string)//debug 模式//Debug: bool
})

解释:
jwtmiddleware.New是配置中间件的错误返回,是否为调试模式,机密秘钥,加密模式等
app.Use(jwtHandler.Serve) 是把中间件注册到处理程序中
注册次中间件的路由,中间件每一次都会去获取header头Authorization字段用户判断

生成加密串过程

token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{"nick_name": "iris","email":"go-iris@qq.com","id":"1","iss":"Iris","iat":time.Now().Unix(),"jti":"9527","exp":time.Now().Add(10*time.Hour * time.Duration(1)).Unix(),
})

把token已约定的加密方式和加密秘钥加密,当然也可以使用不对称加密

tokenString, _ := token.SignedString([]byte("My Secret"))

登录时候,把tokenString返回给客户端,然后需要登录的页面就在header上面附此字符串

eg: header["Authorization"] = "bears "+tokenString

在需要验证的地方,可以插入该中间件,关于中间件的使用可以参考上一篇论文:

user := app.Party("/user")
user.Post("/register", userRegisterHandler)
user.Post("/login", userLoginHandler)
// 这里的/profile路由的返回结果是用户的个人信息,因此可以知道,token的验证必要的,因此,我们使用jwtHandler.Serve进行token的验证
user.Get("/profile", jwtHandler.Serve, userTokenHandler, userProfileHandler)

上面提到了验证的方法,那么服务端如何生成token呢?

下面是一个服务端生成token返回给用户的简单例子:

可以知道,JWT token的生成是在登录的时候发生的,因此下面是userLoginHandler的代码:

func userLoginHandler(ctx iris.Context) {phone := ctx.FormValue("phone")password := ctx.FormValue("password")/* 这里省去了对用户的验证,在实际使用过程中需要验证用户是否存在,密码是否正确 */token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{"phone":    phone,"password": password,"exp":      time.Now().Add(time.Hour * 2).Unix(), // 添加过期时间为2个小时})// 这里的密钥和前面的必须一样tokenString, _ := token.SignedString([]byte("My Secret"))tokenResponse := helper.Token_Response{Code: 200,Msg:  "登录成功!",Data: map[string]string{"token": tokenString}}ctx.JSON(tokenResponse)
}

在Go IRIS中使用JWT相关推荐

  1. 如何简单的在 ASP.NET Core 中集成 JWT 认证?

    前情提要:ASP.NET Core 使用 JWT 搭建分布式无状态身份验证系统 文章超长预警(1万字以上),不想看全部实现过程的同学可以直接跳转到末尾查看成果或者一键安装相关的 nuget 包 自上一 ...

  2. ASP.Net Core 3.1 中使用JWT认证

    JWT认证简单介绍 关于Jwt的介绍网上很多,此处不在赘述,我们主要看看jwt的结构. JWT主要由三部分组成,如下: HEADER.PAYLOAD.SIGNATURE HEADER包含token的元 ...

  3. ASP.NET Core WebAPI中使用JWT Bearer认证和授权

    为什么是 JWT Bearer ASP.NET Core 在 Microsoft.AspNetCore.Authentication 下实现了一系列认证, 包含 Cookie, JwtBearer,  ...

  4. aspnet core 2.1中使用jwt从原理到精通二

    在aspnet core中,自定义jwt管道验证 有了上一节的内容作为基础,那这点也是非常容易的,关键点在中间件,只是把上一级在测试类中的自定义验证放到中间件中来即可, 不过需要注意:中间件 的位置很 ...

  5. jwt token 过期刷新_如何在SpringBoot中集成JWT(JSON Web Token)鉴权

    这篇博客主要是简单介绍了一下什么是JWT,以及如何在Spring Boot项目中使用JWT(JSON Web Token). 1.关于JWT 1.1 什么是JWT 老生常谈的开头,我们要用这样一种工具 ...

  6. 在SPA应用中利用JWT进行身份验证

    版权声明:本文为博主chszs的原创文章,未经博主允许不得转载. https://blog.csdn.net/chszs/article/details/79639919 在SPA应用中利用JWT进行 ...

  7. jwt php tp5,TP5框架中使用JWT的方法示例

    本文实例讲述了TP5框架中使用JWT的方法.共享给大家供大家参考,详细如下: 可以直接去github上下载,也可以使用composer 使用composer的话要保证你的电脑上安装了composer, ...

  8. 关于 IdentityServer4 中的 Jwt Token 与 Reference Token

    原文:关于 IdentityServer4 中的 Jwt Token 与 Reference Token OpenID Connect(Core),OAuth 2.0(RFC 6749),JSON W ...

  9. delphi接口带上请求头是什么意思_Gin框架中使用JWT进行接口验证

    背景: 在如今前后端分离开发的大环境中,我们需要解决一些登陆,后期身份认证以及鉴权相关的事情,通常的方案就是采用请求头携带token的方式进行实现.本篇文章主要分享下在Golang语言下使用jwt-g ...

最新文章

  1. 假装不知道有尽头(博弈论的诡计)
  2. 中小企业如何规避因员工跳槽而产生的风险?
  3. opensource项目_最佳Opensource.com:教程
  4. 大数据之-Hadoop之HDFS_HDFS的内容介绍---大数据之hadoop工作笔记0047
  5. python画3d图-使用python绘制3d的图形
  6. python入门爬虫案例_[Python入门学习]-爬虫项目案例讲解
  7. 07《基于深度学习的车标识别方法研究》学习总结
  8. c 语言入门自学app,C语言入门学习软件
  9. 【python 走进NLP】hanNLP 简繁拼音转换
  10. 神仙打架!今年计算机考研爆炸实况!
  11. 架构师之路---面向过程和面向对象 王泽宾
  12. 简单三步快速实现内网穿透
  13. 中职计算机应用综合试题精选,2015中职计算机应用专业全真模拟试卷(一).doc...
  14. 美的智能SPA微气泡可视化冲牙器体验
  15. 国外云盘(如Rapidgator)免费下载姿势详解
  16. 计算机每次关机需要配置,电脑关机,详细教您怎么设置电脑定时关机
  17. 如何返回正确与错误信息
  18. 感受山猫之力 Ubuntu 10.04 LTS试用手记
  19. TCP的三次握手与四次挥手基本理解
  20. c++ 编译DLL和使用DLL

热门文章

  1. HTTP及HTTPS协议
  2. 论文中有关DEAP数据库介绍,自己写论文时可调用!
  3. matlab中怎么使用svm,关于如何在Matlab中如何使用libsvm
  4. c语言图像处理傅里叶函数,数字图像的傅里叶变换.doc
  5. 华为金融行业解决方案讨论
  6. python传入参数加星号,python 函数参数的传递(参数带星号的说明) 元组传递 字典传递...
  7. 当雅虎CEO梅耶尔成为乔布斯:她为何没能挽回雅虎颓势
  8. 阿里云态势感知服务使用教程
  9. 微信小程序(手机登录60S倒计时+微信登录页面+限制时间次数频率)
  10. ACL2022 | 文本生成的相关前沿进展