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

JWT及单点登录实现

JWT发展简史

JWT Token

JSON Web Token (JWT,RFC 7519 (opens new window)),是为了在网络应用环境间传递声明而执行的一种基于 JSON 的开放标准((RFC 7519)。

ID Token

OIDC (OpenID Connect) 协议 (opens new window)对 OAuth 2.0 协议 (opens new window)最主要的一个扩展就是 ID Token 数据结构。ID Token 相当于用户的身份凭证,开发者的前端访问后端接口时可以携带 ID Token,开发者服务器可以校验用户的 ID Token 以确定用户身份,验证通过后返回相关资源。

传统玩法

当浏览器向服务器发送登录请求时,验证通过之后,会将用户信息存入seesion中,然后服务器会生成一个sessionId放入cookie中,随后返回给浏览器。

当浏览器再次发送请求时,会在请求头部的cookie中放入sessionId,将请求数据一并发送给服务器。

服务器就可以再次从seesion获取用户信息,整个流程完毕!

通常在服务端会设置seesion的时长,例如 30 分钟没有活动,会将已经存放的用户信息从seesion中移除。

同时,在服务端也可以通过seesion来判断当前用户是否已经登录,如果为空表示没有登录,直接跳转到登录页面;如果不为空,可以从session中获取用户信息即可进行后续操作。

这种场景单体程序没有问题,即使用户量增加,可以用公用session数据库,微软基本就这样玩过。

Redis登场

为了解决效能问题,以及redis出现,于是有了redis解决登录这个问题:

将各个应用程序与内存数据库redis相连,对登录成功的用户信息进行一定的算法加密,生成的ID被称为token,将token还有用户的信息存入redis;等用户再次发起请求的时候,将token还有请求数据一并发送给服务器,服务端验证token是否存在redis中,如果存在,表示验证通过,如果不存在,告诉浏览器跳转到登录页面,流程结束。

token方案保证了服务的无状态,所有的信息都是存在分布式缓存中。基于分布式存储,这样可以水平扩展来支持高并发。

当然,现在springboot还提供了session共享方案,类似token方案将session存入到redis中,在集群环境下实现一次登录之后,每个服务器都可以获取到用户信息。

JWT 登场

JWT全称JSON Web Token,实现过程简单的说就是用户登录成功之后,将用户的信息进行加密,然后生成一个token返回给客户端,与传统的session交互没太大区别。

目的是:不用缓存数据库redis来实现用户信息的共享,以达到一次登录,处处可见的效果呢?

技术手段就是客户端携带着token,然后根据规则解析。

JWT构成

因为是标准所以,构成格式是有规则的:

三段信息用.链接 header,paylaod,signature

  • 第一部分:我们称它为头部(header),用于存放token类型和加密协议,一般都是固定的;
  • 第二部分:我们称其为载荷(payload),用户数据就存放在里面;
  • 第三部分:是签证(signature),主要用于服务端的验证;

header 分为两部分:都是json表达式

JWT的头部承载两部分信息:

  • 声明类型,这里是JWT;
  • 声明加密的算法,通常直接使用 HMAC SHA256;

paylaod :

载荷就是存放有效信息的地方,这些有效信息包含三个部分:

  • 标准中注册的声明;
  • 公共的声明;
  • 私有的声明;

其中,标准中注册的声明 (建议但不强制使用)包括如下几个部分

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

公共的声明部分: 公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息,但不建议添加敏感信息,因为该部分在客户端可解密。

私有的声明部分: 私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为base64是对称解密的,意味着该部分信息可以归类为明文信息。

signature

signature = 加密( base64UrlEncode(header) + '.' + base64UrlEncode(payload) );

保护好服务端secret私钥非常重要,因为私钥可以对数据进行验证、解密!

单点登录

Single sign-on (SSO) is an authentication scheme that allows a user to log in with a single ID and password to any of several related, yet independent, software systems.

单点登录(SingleSignOn,SSO),就是通过用户的一次性鉴别登录。当用户在身份认证服务器上登录一次以后,即可获得访问所有信任的应用系统。

为何单点登录

一个公司有n多系统,每个系统有账号密码,比如几十个搞,如何搞?社交媒体有n多网站应用,各类用户和密码,很难整,有没有可能,只记住一个用户密码,其他都同行,这就是单点登录想解决的问题,衍生出各类逻辑问题,对应的就是安全,技术问题等等。

如何单点登录

有一个解决方案,我将我的身份委托给我需要使用的所有网站都信任的单一安全服务,我只需要记住这个安全服务的账号密码,所有其他网站自身不需要具备验证身份的能力,统一由安全服务确认用户身份。

这就是Single Sign On ,单点登录。

JWT实现单点登录

  1. 因为是标准,所以不同的语言平台都有对应的实现接口
  2. 需要一个公共的身份管理中心
  3. 管理身份和各类应用
  4. 分配应用和用户的关系,完成对应业务系统的身份同步
  5. 身份管理中心登陆后,点击业务应用,验证后,携带idtoken,跳转业务系统sso地址
  6. 各类应用根据jwt的规则,有对应的sso地址,用以解析IDtoken,实现业务系统的登录
  7. 业务系统自动跳转身份中心登录入口,重新转向业务地址
  8. 对应解决单点登出接口,实现各个业务应用同步

相关文章:

  • window.setInterval(func,interval)定时器
  • Java | Leetcode Java题解之第137题只出现一次的数字II
  • 高质量 HarmonyOS 权限管控流程
  • 尝试使用blazor(二)Blazor WebAssembly(WASM)与Server之间有什么区别?
  • Python | 洗盘子(栈)
  • 获得抖音商品评论 API 返回值
  • 一个例子了解c++的指针数组和数组指针
  • Linux网络编程——概念及实现双方聊天
  • mingw64,clang,gcc
  • C# Maui 报错:程序“[15748] MauiApp1.exe”已退出,返回值为 2147942405 (0x80070005)
  • 简说SQLServer
  • cocos入门6:向量简介
  • 升级最新版openssh-9.7p1及openssl-1.1.1h详细步骤及常见问题总结
  • 【C++题解】1254. 求车速
  • 【2024最新华为OD-C/D卷试题汇总】[支持在线评测] 运输时间(200分) - 三语言AC题解(Python/Java/Cpp)
  • “大数据应用场景”之隔壁老王(连载四)
  • ABAP的include关键字,Java的import, C的include和C4C ABSL 的import比较
  • IIS 10 PHP CGI 设置 PHP_INI_SCAN_DIR
  • JDK9: 集成 Jshell 和 Maven 项目.
  • mockjs让前端开发独立于后端
  • seaborn 安装成功 + ImportError: DLL load failed: 找不到指定的模块 问题解决
  • win10下安装mysql5.7
  • 开发基于以太坊智能合约的DApp
  • 如何设计一个比特币钱包服务
  • 原创:新手布局福音!微信小程序使用flex的一些基础样式属性(一)
  • hi-nginx-1.3.4编译安装
  • 直播平台建设千万不要忘记流媒体服务器的存在 ...
  • ​【C语言】长篇详解,字符系列篇3-----strstr,strtok,strerror字符串函数的使用【图文详解​】
  • ​14:00面试,14:06就出来了,问的问题有点变态。。。
  • ​探讨元宇宙和VR虚拟现实之间的区别​
  • # 执行时间 统计mysql_一文说尽 MySQL 优化原理
  • #pragma data_seg 共享数据区(转)
  • (C语言)共用体union的用法举例
  • (分布式缓存)Redis分片集群
  • (附源码)python房屋租赁管理系统 毕业设计 745613
  • (附源码)spring boot智能服药提醒app 毕业设计 102151
  • (六)什么是Vite——热更新时vite、webpack做了什么
  • (十二)springboot实战——SSE服务推送事件案例实现
  • (转)关于如何学好游戏3D引擎编程的一些经验
  • .gitignore文件设置了忽略但不生效
  • .NET Core WebAPI中封装Swagger配置
  • .NET 中小心嵌套等待的 Task,它可能会耗尽你线程池的现有资源,出现类似死锁的情况
  • .NET建议使用的大小写命名原则
  • .NET上SQLite的连接
  • .NET使用存储过程实现对数据库的增删改查
  • @FeignClient注解,fallback和fallbackFactory
  • [ C++ ] STL_vector -- 迭代器失效问题
  • [3]Opengl ES着色器
  • [ai笔记9] openAI Sora技术文档引用文献汇总
  • [C++] new和delete
  • [DDR5 Jedec 4-1] 预充电命令 Precharge
  • [docker] Docker容器服务更新与发现之consul
  • [echarts] y轴不显示0
  • [iOS]随机生成UUID通用唯一识别码
  • [Kubernetes]8. K8s使用Helm部署mysql集群(主从数据库集群)