热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Go语言入门篇jwt(jsonwebtoken)权限验证

一。token、cookie、session的区别1。cookieCookie总是保存在客户端中,按在客户端中的存储位置,可分为内存Cookie和硬盘Cookie。内存Cookie

一。token、COOKIE、session的区别

1。COOKIE

COOKIE总是保存在客户端中,按在客户端中的存储位置,可分为内存COOKIE和硬盘COOKIE。

内存COOKIE由浏览器维护,保存在内存中,浏览器关闭后就消失了,其存在时间是短暂的。

硬盘COOKIE保存在硬盘里,有一个过期时间,除非用户手工清理或到了过期时间,硬盘COOKIE不会被删除,其存在时间是长期的。

所以,按存在时间,可分为非持久COOKIE和持久COOKIE。 COOKIE 是一个非常具体的东西,指的就是浏览器里面能永久存储的一种数据,仅仅是浏览器实现的一种数据存储功能。 COOKIE由服务器生成,发送给浏览器,浏览器把COOKIE以key
-value形式保存到某个目录下的文本文件内,下一次请求同一网站时会把该COOKIE发送给服务器。

由于COOKIE是存在客户端上的,所以浏览器加入了一些限制确保COOKIE不会被恶意使用,同时不会占据太多磁盘空间,所以每个域的COOKIE数量是有限的。

2。session

session 从字面上讲,就是会话。这个就类似于你和一个人交谈,你怎么知道当前和你交谈的是张三而不是李四呢?对方肯定有某种特征(长相等)表明他就是张三。

session 也是类似的道理,服务器要知道当前发请求给自己的是谁。为了做这种区分,服务器就要给每个客户端分配不同的“身份标识”,

然后客户端每次向服务器发请求的时候,都带上这个“身份标识”,服务器就知道这个请求来自于谁了。至于客户端怎么保存这个“身份标识”,

可以有很多种方式,对于浏览器客户端,大家都默认采用 COOKIE 的方式。 服务器使用session把用户的信息临时保存在了服务器上,用户离开网站后session会被销毁。这种用户信息存储方式相对COOKIE来说更安全,

可是session有一个缺陷:如果web服务器做了负载均衡,那么下一个操作请求到了另一台服务器的时候session会丢失。

3。token

token的意思是“令牌”,是用户身份的验证方式.

最简单的token组成:

【1】uid(用户唯一的身份标识)
【2】time(当前时间的时间戳)
【3】sign(签名,由token的前几位+盐以哈希算法压缩成一定长的十六进制字符串,
可以防止恶意第三方拼接token请求服务器)。还可以把不变的参数也放进token,避免多次查库 这里的token是指SON Web Token

用户注册之后, 服务器生成一个 JWT token返回给浏览器, 浏览器向服务器请求数据时将 JWT token 发给服务器,

服务器用 signature 中定义的方式解码 

WT 获取用户信息.

一个 JWT token包含3部分: 
【1】header: 告诉我们使用的算法和 token 类型 
【2】Payload: 必须使用 sub key 来指定用户 ID, 还可以包括其他信息比如 email, username 等. 
【3】Signature: 用来保证 JWT 的真实性. 可以使用不同算法 

Go语言入门篇-jwt(json web token)权限验证

二。jwt(json web token)权限验证

完整代码:

  1 package main
  2 
  3 import (
  4     "log"
  5     "net/http"
  6     "github.com/codegangsta/negroni"
  7     "encoding/json"
  8     "fmt"
  9     "strings"
 10     "github.com/dgrijalva/jwt-go"
 11     "time"
 12     "github.com/dgrijalva/jwt-go/request"
 13 )
 14 
 15 /**
 16 说明:
 17 客户端通过在request对象header里添加token参数,发送到服务端。
 18 服务端再拿出token进行比对。
 19 token的第一次产生是发生在login检查账户存在并且正确之后,为该用户赋予一块令牌(加密字符串)
 20 并将token放入response的header里。客户端登陆成功后,从response里取出token。并在以后操作request请求。
 21 都保持在header里添加该段令牌,令牌有效期失效后,只有重新login,才能获取新的令牌。
 22 */
 23 const (
 24     //SecretKey = "welcome to wangshubo's blog"
 25     SecretKey = "I have login"
 26 )
 27 
 28 func fatal(err error) {
 29     if err != nil {
 30         log.Fatal(err)
 31     }
 32 }
 33 
 34 type UserCredentials struct {
 35     Username string `json:"username"`
 36     Password string `json:"password"`
 37 }
 38 
 39 type User struct {
 40     ID       int    `json:"id"`
 41     Name     string `json:"name"`
 42     Username string `json:"username"`
 43     Password string `json:"password"`
 44 }
 45 
 46 type Response struct {
 47     Data string `json:"data"`
 48 }
 49 
 50 type Token struct {
 51     Token string `json:"token"`
 52 }
 53 
 54 func StartServer() {
 55 
 56     http.HandleFunc("/login", LoginHandler)
 57 
 58     http.Handle("/resource", negroni.New(
 59         negroni.HandlerFunc(ValidateTokenMiddleware),
 60         negroni.Wrap(http.HandlerFunc(ProtectedHandler)),
 61     ))
 62 
 63     log.Println("Now listening...")
 64     http.ListenAndServe(":8080", nil)
 65 }
 66 
 67 func main() {
 68     StartServer()
 69 }
 70 
 71 func ProtectedHandler(w http.ResponseWriter, r *http.Request) {
 72 
 73     response := Response{"Gained access to protected resource !"}
 74     JsonResponse(response, w)
 75 
 76 }
 77 
 78 //服务端生成token,并放入到response的header
 79 /**
 80 JWT由三部份组成:
 81 * Header:头部 (对应:Header)
 82 * Claims:声明 (对应:Payload)
 83 * Signature:签名 (对应:Signature)
 84 */
 85 func LoginHandler(w http.ResponseWriter, r *http.Request) {
 86 
 87     var u *User=new(User)
 88 
 89     var user UserCredentials
 90 
 91     err := json.NewDecoder(r.Body).Decode(&user)
 92 
 93     if err != nil {
 94         w.WriteHeader(http.StatusForbidden)
 95         fmt.Fprint(w, "Error in request")
 96         return
 97     }
 98 
 99     //验证是身份:若用户是someone,则生成token
100     if strings.ToLower(user.Username) != "someone" {
101         if user.Password != "p@ssword" {
102             w.WriteHeader(http.StatusForbidden)
103             fmt.Println("Error logging in")
104             fmt.Fprint(w, "Invalid credentials")
105             return
106         }
107     }
108 
109     //1。生成token
110     token := jwt.New(jwt.SigningMethodHS256)
111     claims := make(jwt.MapClaims)
112     //2。添加令牌关键信息
113     //添加令牌期限
114     claims["exp"] = time.Now().Add(time.Hour * time.Duration(1)).Unix()
115     claims["iat"] = time.Now().Unix()
116     claims["id"]=u.ID
117     claims["userName"]=u.Username
118     claims["password"]=u.Password
119     token.Claims = claims
120 
121     fmt.Println(claims)
122 
123     if err != nil {
124         w.WriteHeader(http.StatusInternalServerError)
125         fmt.Fprintln(w, "Error extracting the key")
126         fatal(err)
127     }
128 
129     //获取令牌
130     tokenString, err := token.SignedString([]byte(SecretKey))
131     if err != nil {
132         w.WriteHeader(http.StatusInternalServerError)
133         fmt.Fprintln(w, "Error while signing the token")
134         fatal(err)
135     }
136 
137     //2。将生成的token放入到header
138     response := Token{tokenString}
139     JsonResponse(response, w)
140 
141 }
142 
143 //验证Token
144 func ValidateTokenMiddleware(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
145     token, err := request.ParseFromRequest(r, request.AuthorizationHeaderExtractor,
146         func(token *jwt.Token) (interface{}, error) {
147             return []byte(SecretKey), nil
148         })
149 
150     if err == nil {
151         if token.Valid {
152             next(w, r)
153         } else {
154             w.WriteHeader(http.StatusUnauthorized)
155             fmt.Fprint(w, "Token is not valid")
156         }
157     } else {
158         w.WriteHeader(http.StatusUnauthorized)
159         fmt.Fprint(w, "Unauthorized access to this resource")
160     }
161 
162 }
163 
164 func JsonResponse(response interface{}, w http.ResponseWriter) {
165     json, err := json.Marshal(response)
166     if err != nil {
167         http.Error(w, err.Error(), http.StatusInternalServerError)
168         return
169     }
170     w.WriteHeader(http.StatusOK)
171     w.Header().Set("Content-Type", "application/json")
172     w.Write(json)
173 }
View Code
推荐阅读
  • SpringBoot整合SpringSecurity+JWT实现单点登录
    SpringBoot整合SpringSecurity+JWT实现单点登录,Go语言社区,Golang程序员人脉社 ... [详细]
  • 如何查询zone下的表的信息
    本文介绍了如何通过TcaplusDB知识库查询zone下的表的信息。包括请求地址、GET请求参数说明、返回参数说明等内容。通过curl方法发起请求,并提供了请求示例。 ... [详细]
  • 本文介绍了Windows Vista操作系统中的用户账户保护功能,该功能是为了增强系统的安全性而设计的。通过对Vista测试版的体验,可以看到系统在安全性方面的进步。该功能的引入,为用户的账户安全提供了更好的保障。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • Go GUIlxn/walk 学习3.菜单栏和工具栏的具体实现
    本文介绍了使用Go语言的GUI库lxn/walk实现菜单栏和工具栏的具体方法,包括消息窗口的产生、文件放置动作响应和提示框的应用。部分代码来自上一篇博客和lxn/walk官方示例。文章提供了学习GUI开发的实际案例和代码示例。 ... [详细]
  • 数字账号安全与数据资产问题的研究及解决方案
    本文研究了数字账号安全与数据资产问题,并提出了解决方案。近期,大量QQ账号被盗事件引起了广泛关注。欺诈者对数字账号的价值认识超过了账号主人,因此他们不断攻击和盗用账号。然而,平台和账号主人对账号安全问题的态度不正确,只有用户自身意识到问题的严重性并采取行动,才能推动平台优先解决这些问题。本文旨在提醒用户关注账号安全,并呼吁平台承担起更多的责任。令牌云团队对此进行了长期深入的研究,并提出了相应的解决方案。 ... [详细]
  • 本文介绍了前端人员必须知道的三个问题,即前端都做哪些事、前端都需要哪些技术,以及前端的发展阶段。初级阶段包括HTML、CSS、JavaScript和jQuery的基础知识。进阶阶段涵盖了面向对象编程、响应式设计、Ajax、HTML5等新兴技术。高级阶段包括架构基础、模块化开发、预编译和前沿规范等内容。此外,还介绍了一些后端服务,如Node.js。 ... [详细]
  • 本文记录了在vue cli 3.x中移除console的一些采坑经验,通过使用uglifyjs-webpack-plugin插件,在vue.config.js中进行相关配置,包括设置minimizer、UglifyJsPlugin和compress等参数,最终成功移除了console。同时,还包括了一些可能出现的报错情况和解决方法。 ... [详细]
  • 本文介绍了如何使用JSONObiect和Gson相关方法实现json数据与kotlin对象的相互转换。首先解释了JSON的概念和数据格式,然后详细介绍了相关API,包括JSONObject和Gson的使用方法。接着讲解了如何将json格式的字符串转换为kotlin对象或List,以及如何将kotlin对象转换为json字符串。最后提到了使用Map封装json对象的特殊情况。文章还对JSON和XML进行了比较,指出了JSON的优势和缺点。 ... [详细]
  • 图像因存在错误而无法显示 ... [详细]
  • GPT-3发布,动动手指就能自动生成代码的神器来了!
    近日,OpenAI发布了最新的NLP模型GPT-3,该模型在GitHub趋势榜上名列前茅。GPT-3使用的数据集容量达到45TB,参数个数高达1750亿,训练好的模型需要700G的硬盘空间来存储。一位开发者根据GPT-3模型上线了一个名为debuid的网站,用户只需用英语描述需求,前端代码就能自动生成。这个神奇的功能让许多程序员感到惊讶。去年,OpenAI在与世界冠军OG战队的表演赛中展示了他们的强化学习模型,在限定条件下以2:0完胜人类冠军。 ... [详细]
author-avatar
沫小兮
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有