Gitlib Gitlib
首页
  • 分类
  • 标签
  • 归档
  • Golang开发实践万字总结
  • MySQL核心知识汇总
  • Redis实践总结
  • MQ实践万字总结
  • Docker数据持久化总结
  • Docker网络模式深度解读
  • 常用游戏反外挂技术总结
  • 读书笔记
  • 心情杂货
  • 行业杂谈
  • 友情链接
关于我
GitHub (opens new window)

Ravior

以梦为马,莫负韶华
首页
  • 分类
  • 标签
  • 归档
  • Golang开发实践万字总结
  • MySQL核心知识汇总
  • Redis实践总结
  • MQ实践万字总结
  • Docker数据持久化总结
  • Docker网络模式深度解读
  • 常用游戏反外挂技术总结
  • 读书笔记
  • 心情杂货
  • 行业杂谈
  • 友情链接
关于我
GitHub (opens new window)
  • 基础架构

    • LNMP架构下各项配置优化总结
    • HAProxy实践详解
    • Keepalived的部署及应用
    • ELK日志分析系统入门
    • 简单队列服务:HTTPSQS
    • 基于Redis使用令牌桶算法实现流量控制
    • 基于JWT实现Token认证
      • 传统身份验证
      • 基于Token的身份验证
      • JWT
        • 头部(HEADER)
        • 载荷(PAYLOAD)
        • 标准的注册声明:
        • 公共的声明
        • 私有的声明
        • 签证(SIGNATURE)
        • JWT使用方式
    • 布隆过滤,实现亿级数据快速查找
    • 深入理解一致性Hash原理
    • Redis和Zookeeper分布式锁实现
  • MQ

  • 微服务

  • 分布式

  • 高并发

  • 大数据

  • 容器化

  • 架构设计
  • 基础架构
Ravior
2018-03-23
目录

基于JWT实现Token认证

JSON Web Token(JWT)是目前最流行的跨域身份验证解决方案, 定义了一种紧凑且自包含的,用于在多方传递JSON对象的技术。

在了解JWT之前,先了解一下目前两种主流身份验证方式:传统身份验证、基于Token的身份验证。

# 传统身份验证

HTTP 是一种无状态的协议,没有上下文会话机制,每一条HTTP请求都是相互独立的。为了识别用户和保存用户的状态,可以依靠Cookie和Session来处理,流程如下:

  1. 客户端使用用户名密码进行认证
  2. 服务端生成并存储 Session,将 SessionID 通过 Cookie 返回给客户端
  3. 客户端访问需要认证的接口时在 Cookie 中携带 SessionID
  4. 服务端通过 SessionID 查找 Session 并进行鉴权,返回给客户端需要的数据

jwt

这种身份验证方法,需要在服务端存储为登录的用户生成的Session,这些Session可能会存储在内存,磁盘,或者数据库里。

# 基于Token的身份验证

使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录。大概的流程是这样的:

  1. 客户端使用用户名跟密码请求登录
  2. 服务端收到请求,去验证用户名与密码
  3. 验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端
  4. 客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里
  5. 客户端每次向服务端请求资源的时候需要带着服务端签发的 Token
  6. 服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据

jwt

# JWT

JWT的原则是在服务器身份验证之后,将生成一个JSON对象并将其发送回用户。,当用户与服务器通信时,客户在请求中发回JSON对象。服务器仅依赖于这个JSON对象来标识用户。为了防止用户篡改数据,服务器将在生成对象时添加签名。 与基于Token的身份验证方法一样,服务器不保存任何会话数据,即服务器变为无状态,使其更容易扩展。

jwt

Jwt 形式的 token 一般分为 3 个部分,分别是 Header,Payload,Signature,这三个部分使用 .分隔**(格式:Header.Payload.Signature) 。其中前两部分使用Base64URL**编码,未经加密处理,第三个部分使用 RSA 加密。

jwt

# 头部(HEADER)

HEADER主要为了描述该JWT的最基本信息,主要包含两个部分:声明类型和声明加密算法(通常直接使用HMAC,SHA256)

{
  "alg": "HS256",
  "typ": "JWT"
}
1
2
3
4

# 载荷(PAYLOAD)

载荷主要是存放有效信息,这些信息按照职能可以分成三个部分:

  • 标准的注册声明
  • 公共的声明
  • 私有的声明
{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}
1
2
3
4
5

# 标准的注册声明:

  • iss:jwt签发者
  • sub:jwt所面向的用户
  • aud:接收jwt的一方
  • exp:jwt的过期时间,这个过期时间必须要大于签发时间
  • nbf:定义在什么时间之前,该jwt都是不可用的
  • iat:jwt的签发时间
  • jti:jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击

# 公共的声明

公共的声明可以添加任何的信息。一般这里我们会存放一下用户的基本信息(非敏感信息)

# 私有的声明

私有声明是提供者和消费者所共同定义的声明,不要存放敏感信息。

这些声明分类和字段,只是建议不强制使用。

# 签证(SIGNATURE)

JWT的第三部分是一个签证信息,这个签证信息主要由三个部分组成:Header(BASE64后),Payload(BASE64后),secret。

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)
1
2
3
4

jwt

因为header和payload内容都是明文记录(base64编码,任何人获取到jwt之后都可以解码),除非记录的是加密数据,否则不排除泄露隐私数据的可能。不推荐在jwt中记录任何敏感数据。

jwt

JWT 默认是不加密,不加密的情况下,不要写入敏感数据 ,当然也可以在生成原始 Token 以后,用密钥再加密一次。

# JWT使用方式

客户端接收服务器返回的JWT,将其存储在Cookie或localStorage中。此后,客户端将在与服务器交互中都会带JWT。如果将它存储在Cookie中,就可以自动发送,但是不会跨域,因此一般是将它放入HTTP请求的Header Authorization字段中。

Authorization: Bearer <token>
1

当跨域时,也可以将JWT被放置于POST请求的数据主体中。

#JWT#API网关
上次更新: 2022/12/02, 22:04:34
基于Redis使用令牌桶算法实现流量控制
布隆过滤,实现亿级数据快速查找

← 基于Redis使用令牌桶算法实现流量控制 布隆过滤,实现亿级数据快速查找→

最近更新
01
常用游戏反外挂技术总结
11-27
02
Golang开发实践万字总结
11-11
03
Redis万字总结
10-30
更多文章>
Theme by Vdoing | Copyright © 2011-2022 Ravior | 粤ICP备17060229号-3 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式