Go实战--golang中使用JWT(JSON Web Token)

go使用jwt对前端用户身份通过token认证 文章目录一、导入工具包jwt-go生成token二、在登录验证接口中使用token生成方法三、解析前端请求头中的token四、中间件来验证客户端传递过来的token五、使用示例 背景前沿:近期项目需要对前端提供的部分接口做身份认证拦截,需要在登录成功后生成一个token返回给前端,后续需要进行验证的接口需要在请求头中携带token才能正常请求数据 一、导入工具包jwt-go生成token 命令导入安装包 go get -u github.com/dgrijalva/jwt-go 可在使用时包头直接引 阅读详情

今天就来跟大家简单介绍一下golang中如何使用token,当然是要依赖一下github上的优秀的开源库了。

首先,要搞明白一个问题,token、cookie、session的区别。

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

内存Cookie由浏览器维护,保存在内存中,浏览器关闭后就消失了,其存在时间是短暂的。硬盘Cookie保存在硬盘里,有一个过期时间,除非用户手工清理或到了过期时间,硬盘Cookie不会被删除,其存在时间是长期的。所以,按存在时间,可分为非持久Cookie和持久Cookie。

cookie 是一个非常具体的东西,指的就是浏览器里面能永久存储的一种数据,仅仅是浏览器实现的一种数据存储功能。

cookie由服务器生成,发送给浏览器,浏览器把cookie以key-value形式保存到某个目录下的文本文件内,下一次请求同一网站时会把该cookie发送给服务器。由于cookie是存在客户端上的,所以浏览器加入了一些限制确保cookie不会被恶意使用,同时不会占据太多磁盘空间,所以每个域的cookie数量是有限的。

Session

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

session 也是类似的道理,服务器要知道当前发请求给自己的是谁。为了做这种区分,服务器就要给每个客户端分配不同的“身份标识”,然后客户端每次向服务器发请求的时候,都带上这个“身份标识”,服务器就知道这个请求来自于谁了。至于客户端怎么保存这个“身份标识”,可以有很多种方式,对于浏览器客户端,大家都默认采用 cookie 的方式。

服务器使用session把用户的信息临时保存在了服务器上,用户离开网站后session会被销毁。这种用户信息存储方式相对cookie来说更安全,可是session有一个缺陷:如果web服务器做了负载均衡,那么下一个操作请求到了另一台服务器的时候session会丢失。

Token 
token的意思是“令牌”,是用户身份的验证方式,最简单的token组成:uid(用户唯一的身份标识)、time(当前时间的时间戳)、sign(签名,由token的前几位+盐以哈希算法压缩成一定长的十六进制字符串,可以防止恶意第三方拼接token请求服务器)。还可以把不变的参数也放进token,避免多次查库

这里的token是指SON Web Token: 
JSON Web Token (JWT) is a compact URL-safe means of representing claims to be transferred between two parties. The claims in a JWT are encoded as a JSON object that is digitally signed using JSON Web Signature (JWS).

使用JWT进行认证 
JSON Web Tokens (JWT) are a more modern approach to authentication.

As the web moves to a greater separation between the client and server, JWT provides a wonderful alternative to traditional cookie based authentication models.

JWTs provide a way for clients to authenticate every request without having to maintain a session or repeatedly pass login credentials to the server.

用户注册之后, 服务器生成一个 JWT token返回给浏览器, 浏览器向服务器请求数据时将 JWT token 发给服务器, 服务器用 signature 中定义的方式解码 
JWT 获取用户信息.

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


JWT应用
上面说了那么多,接下来就是要coding了。 
用到的开源库: 
github.com/codegangsta/negroni 
Idiomatic HTTP Middleware for Golang 
http的一个中间件

github.com/dgrijalva/jwt-go 
Golang implementation of JSON Web Tokens (JWT)

github.com/dgrijalva/jwt-go/request

这里分两个api,一个是通过login获取token,然后根据token访问另一个api。首先看看login是如何生成token的: 
当然首先是验证用户名和密码,为了节省篇幅这里只是代码片段,完整代码最后献上。

    token := jwt.New(jwt.SigningMethodHS256)
    claims := make(jwt.MapClaims)
    claims["exp"] = time.Now().Add(time.Hour * time.Duration(1)).Unix()
    claims["iat"] = time.Now().Unix()
    token.Claims = claims

    if err != nil {
        w.WriteHeader(http.StatusInternalServerError)
        fmt.Fprintln(w, "Error extracting the key")
        fatal(err)
    }

    tokenString, err := token.SignedString([]byte(SecretKey))
    if err != nil {
        w.WriteHeader(http.StatusInternalServerError)
        fmt.Fprintln(w, "Error while signing the token")
        fatal(err)
    }


接下来就是验证token的中间件了:

    token, err := request.ParseFromRequest(r, request.AuthorizationHeaderExtractor,
        func(token *jwt.Token) (interface{}, error) {
            return []byte(SecretKey), nil
        })

    if err == nil {
        if token.Valid {
            next(w, r)
        } else {
            w.WriteHeader(http.StatusUnauthorized)
            fmt.Fprint(w, "Token is not valid")
        }
    } else {
        w.WriteHeader(http.StatusUnauthorized)
        fmt.Fprint(w, "Unauthorized access to this resource")
    }


最后完整代码:

package main

import (
    "encoding/json"
    "fmt"
    "log"
    "net/http"
    "strings"
    "time"

    "github.com/codegangsta/negroni"
    "github.com/dgrijalva/jwt-go"
    "github.com/dgrijalva/jwt-go/request"
)

const (
    SecretKey = "welcome to wangshubo's blog"
)

func fatal(err error) {
    if err != nil {
        log.Fatal(err)
    }
}

type UserCredentials struct {
    Username string `json:"username"`
    Password string `json:"password"`
}

type User struct {
    ID       int    `json:"id"`
    Name     string `json:"name"`
    Username string `json:"username"`
    Password string `json:"password"`
}

type Response struct {
    Data string `json:"data"`
}

type Token struct {
    Token string `json:"token"`
}

func StartServer() {

    http.HandleFunc("/login", LoginHandler)

    http.Handle("/resource", negroni.New(
        negroni.HandlerFunc(ValidateTokenMiddleware),
        negroni.Wrap(http.HandlerFunc(ProtectedHandler)),
    ))

    log.Println("Now listening...")
    http.ListenAndServe(":8080", nil)
}

func main() {
    StartServer()
}

func ProtectedHandler(w http.ResponseWriter, r *http.Request) {

    response := Response{"Gained access to protected resource"}
    JsonResponse(response, w)

}

func LoginHandler(w http.ResponseWriter, r *http.Request) {

    var user UserCredentials

    err := json.NewDecoder(r.Body).Decode(&user)

    if err != nil {
        w.WriteHeader(http.StatusForbidden)
        fmt.Fprint(w, "Error in request")
        return
    }

    if strings.ToLower(user.Username) != "someone" {
        if user.Password != "p@ssword" {
            w.WriteHeader(http.StatusForbidden)
            fmt.Println("Error logging in")
            fmt.Fprint(w, "Invalid credentials")
            return
        }
    }

    token := jwt.New(jwt.SigningMethodHS256)
    claims := make(jwt.MapClaims)
    claims["exp"] = time.Now().Add(time.Hour * time.Duration(1)).Unix()
    claims["iat"] = time.Now().Unix()
    token.Claims = claims

    if err != nil {
        w.WriteHeader(http.StatusInternalServerError)
        fmt.Fprintln(w, "Error extracting the key")
        fatal(err)
    }

    tokenString, err := token.SignedString([]byte(SecretKey))
    if err != nil {
        w.WriteHeader(http.StatusInternalServerError)
        fmt.Fprintln(w, "Error while signing the token")
        fatal(err)
    }

    response := Token{tokenString}
    JsonResponse(response, w)

}

func ValidateTokenMiddleware(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {

    token, err := request.ParseFromRequest(r, request.AuthorizationHeaderExtractor,
        func(token *jwt.Token) (interface{}, error) {
            return []byte(SecretKey), nil
        })

    if err == nil {
        if token.Valid {
            next(w, r)
        } else {
            w.WriteHeader(http.StatusUnauthorized)
            fmt.Fprint(w, "Token is not valid")
        }
    } else {
        w.WriteHeader(http.StatusUnauthorized)
        fmt.Fprint(w, "Unauthorized access to this resource")
    }

}

func JsonResponse(response interface{}, w http.ResponseWriter) {

    json, err := json.Marshal(response)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    w.WriteHeader(http.StatusOK)
    w.Header().Set("Content-Type", "application/json")
    w.Write(json)
}


通过postman进行验证: 
login: 
这里写图片描述

根据获得token进行get请求: 
这里写图片描述

这里写图片描述

 

--------------------- 
作者:一蓑烟雨1989 
来源:优快云 
原文:https://blog.youkuaiyun.com/wangshubo1989/article/details/74529333 
版权声明:本文为博主原创文章,转载请附上博文链接!

Go实战--golang中使用JWT JSON Web Token 阅读详情

相关推荐

golang的jwt学习笔记

jwt的使用和jwt服务(只有编码)

yasinawolaopo的博客 1064

【Golang学习之旅】使用 JWT 进行身份认证(Token 机制)

是一种基于 JSON 格式的无状态认证机制,广泛应用于 RESTful API 的身份认证。它的基本思想是:服务器在用户登录成功后,生成一个Token(令牌),然后客户端在后续的请求中携带该 Token,服务器通过解析 Token 进行身份验证。无状态:服务器不需要存储 Token 状态,所有信息都包含在 Token 内部。跨平台:基于 JSON 格式,可以在任何支持 HTTP 的环境中使用。自包含:Token 本身包含了身份验证相关的信息,减少了数据库查询。

程序员林北北的博客 1998

Go语言使用golang-jwt/jwt/v4进行JWT鉴权

文章目录1.什么是JWT2.JWT的数据结构2.1 Header2.2 Payload2.3 Signature2.4 Base64URL3使用JWT安装生成Token参考: 最近写的项目中用到了JWT鉴权,因此做个记录 原先的jwt-go仓库已经不再维护,迁移到了github.com/golang-jwt/jwt/v4 但是网上大多数还是v3版本的使用教程,建议使用更加安全的v4 1.什么是JWT JSON Web Token (JWT)是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方

反方向的周-博客 9405

Go实战--golang中使用JWT(JSON Web Token) 使用包 dgrijalva

Go实战--golang中使用JWT(JSON Web Token)wangshubo1989 · 2017-08-13 09:31:02 · 2162 次点击 · 预计阅读时间 7 分钟 · 大约1分钟之前 开始浏览    这是一个创建于 2017-08-13 09:31:02 的文章,其中的信息可能已经有所发展或是发生改变。生命不止,继续 go go go !!!之前写过关于golang中如何...

weixin_40592935的博客 1787

12、Go Gin使用JWT实现认证机制

JWT是JSON Web Token的缩写,是一种跨域认证的解决方案。import ("log"return nil//密钥Username: "小明",Gender: "男",if err!= nil {log.Fatal("签署JET时错误", err)在自定义结构中使用JWT标准中定义的字段*jwt.StandardClaims//标准字段。

qq_39335595的博客 2688

【REST2SQL】11 基于jwt-go生成token与验证

Token 本质是字符串,用于请求时附带在请求头中,校验请求是否合法及判断用户身份。Token 请求时提供,用于校验用户是否具备访问接口的权限。拦截无效请求,降低服务器处理压力;实现第三方 API授权,无需每次都输入用户名密码鉴权;身份校验,防止 CSRF 攻击。JWT(JSON Web Token)是一种用于身份验证和授权的开放标准(RFC 7519),它是一种安全的、轻量级的身份验证方式。JWT由三部分组成:头部(Header)、载荷(Payload)和签名(Signature)。

REST2SQL ,JSON2WEB 1240

go token验证_Go实战--golang中使用JWT(JSON Web Token)-Go语言中文社区

http://blog.youkuaiyun.com/wangshubo1989/article/details/74529333之前写过关于golang中如何使用cookie的博客:实战–go中使用cookie今天就来跟大家简单介绍一下golang中如何使用token,当然是要依赖一下github上的优秀的开源库了。首先,要搞明白一个问题,token、cookie、session的区别。token、cook...

weixin_39950081的博客 683

【Go开源宝藏】JWT-Go 鉴权 | 中间件

【Go开源宝藏】JWT-Go鉴权

面向生活编程 2423

一文读懂 JWT(JSON Web Token)

JWT是一种基于JSON的开放标准(RFC 7519),用于安全传递信息。它具有紧凑、自包含和可验证的特点,常用于用户认证。JWT由三部分组成:Header(算法和类型)、Payload(用户数据)和Signature(防篡改签名)。密钥(Secret)是JWT安全的核心,建议使用32字节随机生成,并妥善保管。JWT支持多种签名算法,如HS256(对称)和RS256(非对称)。其工作流程包括用户登录、服务器签发JWT、客户端存储和后续请求携带验证。虽然JWT具有无状态、可扩展等优点,但也存在无法即时撤销、泄

qq_22328011的博客 1086

delphi-jwt:JWT的Delphi实现

介绍 JWT( )的Delphi实现。 支持的算法 算法 地位 没有任何 :thumbs_up: HS256 :thumbs_up: HS384 :thumbs_up: HS512 :thumbs_up: 以下算法需要第三方库 ES256 :thumbs_up: ES384 :thumbs_up: ES512 :thumbs_up: ES256K 即将推出 PS256 :thumbs_up: PS384 :thumbs_up: PS512 :thumbs_up: RS256 :thumbs_up: RS384 :thumbs_up: RS512 :thumbs_up: 第三方图书馆 ES , PS和RS算法需要第三方库: 。 生成密钥对 # Generate RSA 2048 bits key pair for RS and PS algorithm $ openssl genrsa -out rs-private.pem 2048 $ openssl rsa -in rs-private.pem -pubo

delphi-jose-jwt:JOSE(JSON对象签名和加密)和JWT(JSON Web令牌)的Delphi实现

Delphi JOSE和JWT库 JWT(JSON Web令牌)和JOSE(JSON对象签名和加密)规范套件的实现。 该库通过几种JOSE算法支持JWS(已计划JWE支持)紧凑序列化。 :books: 有关使用Delphi-JOSE的文章 -JWT和身份验证技术介绍(使用Delphi) -了解JSON Web令牌 -使用Delphi-JOSE-JWT生成和验证JWT令牌 -使用JWT使用者来验证JWT的声明 :warning: 重要事项:OpenSSL要求 使用SHA算法的HMAC 在Delphi 10 Seattle之前,HMAC-SHA算法通过Indy库使用OpenSSL,因此,要生成令牌,您应该在服务器系统中具有OpenSSL DLL。 在Delphi 10 Seattle或更新的Delphi版本中,HMAC算法也是System.Hash单元,因此不需要OpenSSL。 使用RSA或ECD

Web开发的身份证:JWT(json web token)令牌使用方法

JWT(JSON Web Token)是一种用于身份验证的机制,通过颁发令牌实现用户登录态保持。JWT由Header、Payload和Signature三部分组成,使用密钥签名确保安全性。工作流程包括登录生成令牌和访问资源时验证令牌。Golang实现中,需定义密钥和Claims结构,使用jwt包生成和验证令牌。验证通常放在中间件中,确保请求安全。JWT类似于现实中的身份证验证机制,为Web服务提供安全认证方案。

liupenglove的专栏 2014

在Ansys Mechanical中对磨损进行建模

在有限元分析中,磨损是通过移动接触表面上的节点来复制材料侵蚀来建模的。仿真迭代更新几何,并在每次更新后重新计算平衡,使过程成为非线性的。Ansys使用将压力、相对运动和材料阻力与表面损失联系起来的经验定律来处理连续介质尺度的磨损。要在Ansys Mechanical中激活磨损建模,必须使用TB,WEAR命令定义专用材料模型。该命令与 TBDATA 相结合,允许用户输入与磨损相关的材料常数,以控制磨损的计算方式以及在接触表面上的应用方式。

jkh920184196的博客 2630

Go 中 JWT 身份验证指南

JSON Web 令牌 (JWT) 是处理在线身份验证的流行方法,您可以使用任何服务器端编程语言实现 JWT 身份验证。对于一般的 JWT 阅读背景知识,我建议通过 LogRocket 博客上的这些文章了解更多关于JWT、最佳实践和使用 JWT 保护 RESTful API的信息。本文旨在帮助您开始使用该包在您的 Go Web 应用程序中实现 JWT 身份验证。golang-jwt由于其特性和易用性,该包是在 Go 中实现 JWT 最流行的包。该包提供了生成和验证 JWT 的功能。

分享身边生活经验blog 2312

Windows下Anaconda换清华镜像源最全指南(含常见问题解决)

本文提供了一份详尽的Windows系统下Anaconda配置清华镜像源的完整指南。针对网络下载缓慢的痛点,文章详细对比了命令行添加与直接编辑配置文件两种主流方法,并重点解决了配置过程中常见的文件缺失、安装失败、环境求解缓慢等疑难问题,帮助用户一劳永逸地提升包管理效率。

brandy的博客 337

银行会计第2课:交易和核算分离的思想

核算作为会计的基础,将交易转化为可量化的信息,而会计则通过整合核算结果,实现对经济活动的全面把控。- 本质:指企业或主体之间发生的、能引起经济利益变动的具体事项,比如采购商品、销售货物、支付工资等,是客观发生的经济事实。可售产品(业务视角的核算对象) + 属性条件(核算的分类,限制等) = 核算类型(会计视角,含有科目分类内容)- 核算:会计人员根据采购发票、入库单等,将这笔交易记为“借:原材料,贷:银行存款”(对事实的会计处理)。- 特点:是核算的源头,不涉及会计处理,仅代表经济行为的发生。

ademen的博客 499

(4)go web开发之 JWT-Token认证机制Access Token与Refresh Token及 jwt-go 库介绍及在项目中使用

介绍 jwt-go: 官方介绍:A go (or ‘golang’ for search engine friendliness) implementation of JSON Web Tokens 意思是 go 语言实现的 json web token。 github地址:https://github.com/dgrijalva/jwt-go 可以查看这篇讲解:https://www.bilibili.com/video/BV14p4y1x7kF?from=search&seid=269440

pythonstrat的博客 4169

Spec-Kit实战:用‘规范驱动开发’重构一个老旧Node.js项目(避坑指南)

本文详细介绍了如何使用Spec-Kit工具通过‘规范驱动开发’(SDD)重构老旧Node.js项目。从逆向工程提取规范到增量改造策略,再到避免典型陷阱,提供了实战指南和避坑技巧,帮助开发者高效实现架构现代化,显著提升代码质量和维护效率。

weixin_42525582的博客 555
上一篇: python中导入其他目录下的模块
下一篇: crontable定时设置案例
cbmljs
博客等级 码龄10年 329粉丝 130原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值