IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> 跨域用户信息判断Token、seeion、jwt -> 正文阅读

[系统运维]跨域用户信息判断Token、seeion、jwt

作者:token keyword

多系统单一位置登录,实现多系统同时登录的一种技术。

单点登录一般用于互相授信的系统,实现单一登录,全系统有效。

三方登录:某系统,使用其他系统的用户,实现本系统登录的方式。解决信息孤岛,信息不对等的实现方案。

Session跨域

所谓Session跨域就是摒弃了系统提供的session,而使用自定义的类似session的机制来保存客户端数据的一种解决方案。

如:通过设置 cookie 的 domian 来实现 cookie 的跨域传递,在 cookie 中传递一个自定义的 session_id 。这个 session_id 是客户端的唯一标记。将这个标记为key,将客户端需要保存的数据作为 value ,在服务端保存(数据库保存或 NOSQL 保存)。这种机制就是Session跨域解决。

Cookie 中的domian属性,表示的是cookie所在的域,默认为请求的地址,如网址为www.baidu.com/test/a,那么domain默认为www.baidu.com。而跨域访问,如域A为 A.test.com ,域B为 B.test.com,那么在域A生产一个令域A和域B都能访问的cookie就要将该cookie的domain设置为.test.com;如果要在域A生产一个令域A不能访问而域B能访问的cookie就要将该cookie的domain设置为B.test.com

Spring Session共享

spring-session 技术是 spring 提供的用于处理集群会话共享的解决方案。spring-session 技术是将用户 session 数据保存到三方存储容器中,如:mysql、redis等。

spring-session 技术是解决同域名下的多服务器集群 session 共享问题的。不能解决跨域 session 共享问题。

Nginx Session 共享

nginx 中的 ip_hash 技术能够将某个 IP 的请求定向到同一台后端,这样依赖这个 ip 下的某个客户和某个后端就能建立器稳固的 session ,IP_HASH 是在 upstream 配置中定义的。

http {
   include       mime.types;
   default_type  application/octet-stream;

   sendfile        on;
   keepalive_timeout  65;

   #在nginx的配置文件中进行负载均衡的配置
   upstream myserver{
     server 127.0.0.1:8080 weight=5;
     server 127.0.0.1:8081 weight=10;
     ip_hash;
   }

 server {
   # 监听的端口
   listen       80;
   server_name  localhost;

   location / {
     root   html;
     # 设置自己的服务
     proxy_pass  http://myserver;
     index  index.html index.htm;
   }

   location = /50x.html {
     root   html;
   }
 }
}

ip_hash 是容易理解的,但是因为仅仅能用 IP 这个因子来分配后端,因此 ip_hash 是有缺陷的,不能在一些情况下使用:

nginx 不是最前端的服务器。ip_hash 要求nginx 一定是最前端的服务器,否则 nginx 得不到正确 ip ,就不能根据 IP 作 hash 。譬如使用的是 squid 为最前端,那么 nginx 取 ip 时只能却道 squid 的服务器 ip 地址,用这个地址来作分流时肯定错乱的。

nginx 的后端还有其他方式的负载均衡。假如 nginx 后端又又其他负载均衡,将请求又通过另外的方式分流了,那么某个客户端的请求肯定不能定位到同一台 session 应用服务器上。

Token 机制

使用token验证机制的优势是:

  • 无状态,可扩展:
    在客户端存储的 Token 是无状态的,并且能够被扩展。基于这种无状态的和不存储 session 信息,负载均衡器能够将用户信息从一台服务器传递到另外的服务器。
  • 安全性:
    请求中发送 token 而不是发送 cookie 能够防止 CSRF(跨站请求伪造)。即使在客户端使用 cookie 存储 token ,cookie 也仅仅是一个存储机制而不是用于认证,不将信息存储在 session 中,让我们少了对 session 的操作

JSON WEB TOKEN(JWT机制)

? JWT是一种紧凑的且自包含的,用于在多方传递 JSON 对象的技术。传递的数据可以使用数字签名增加其安全性。可以使用HMAC加密算法或RSA公钥/私钥加密方式.

紧凑:数据小,可以通过URL,POST参数,请求发送。且数据小代表传输速度块。

自包含:使用 payload 数据块记录用户必要且不隐私的数据,可以有效的减少数据库访问次数,提高代码性能。

JWT一般用于处理用户身份验证数据信息交换

JWT结构

JWT 的数据结构是:A.B.C 由字符点 ‘.’ 来分隔三部分数据。

A-header 头信息

B-payload 载荷

C-Signature 签名

Header

# 数据结构:
{
    "alg":"加密算法名称",
    "typ":"JWT"
}

# alg 是加密算法定义内容,如:HMAC SHA256RSA
# typ 是token类型,这里固定为 JWT

payload

在 payload 数据中一般用于记录实体(通常为用户信息)或其他数据的。主要分为三部分,分别是:已注册信息(registered claims),公开数据(public claims),私有数据(private claims)。

payload 中常用信息有:iss(发行者),exp(到期时间),sub(主题),aud(受众)等。这些都是以注册信息。

公开数据部分一般都会在JWT 注册表中增加定义。避免和已注册信息冲突。

公开数据和私有数据可以由程序员自行定义。

注意:即使 JWT 有签名加密机制,但是 payload 内容都是明文记录,除非记录的是加密数据,否则不排除泄密隐私数据的可能,不推荐在 payload 中记录任何敏感数据。

Signature

签名信息。这是一个由开发者提供的信息。是服务器验证的传递的数据是否安全有效的标准。在生成 JWT 最终数据之前。先使用 header 中定义加密算法,将 header 和 payload 进行加密,并使用点进行连接。如:加密后的 head.加密后的payload。再使用相同的加密算法,对加密后的数据和签名信息进行加密。得到最终结果。

JWT使用

maven依赖

<!-- JWT 核心依赖 -->
<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.18.2</version>
</dependency>
<!-- java开发JWT的依赖jar包 -->
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>

JWT工具类

/**
 * <p>Title: JWTUtil</p >
 * <p>Description: JWT工具类</p >
 *
 * @ author: FT
 * @ CreateTime: 2021/12/31 10:34
 */
public class JWTUtil {
    //服务器的key。用于做加解密的key数据。如果可以使用客户端生成key。当前定常量科比使用
    private static final String SECRET_KEY = "test_web_ab";
    private static final ObjectMapper MAPPER = new ObjectMapper();


    //Secret key
    private static byte[] getSecretKey() {
        return SECRET_KEY.getBytes(StandardCharsets.UTF_8);
    }

    /**
     * 签发jwt,创建token的方法
     *
     * @param id        JWT的唯一身份标识,主要用来作为一次性token,从而回避
     * @param iss       JWT签发者
     * @param subject   JWT所面向用户,payload中记录的public claims。当前环境中就是用户的登录名
     * @param ttlMillis 有效时长,单位毫秒
     * @return token是一一次性的,是为一个用户的有效登录周期准备的token,用户退出或超时,token失效。
     */
    public static String createJWT(String id, String iss, String subject, Long ttlMillis) {
        //加密算法
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        //当前时间
        Long nowMillis = System.currentTimeMillis();
        //当前时间的日期对象
        Date data = new Date(nowMillis);
        // 创建payload的私有声明(根据特定的业务需要添加)
        Map<String, Object> claims = new HashMap<String, Object>();
        claims.put("username", "李四");
        claims.put("password", "1234567890");

        //创建JWT的构建器。使用指定的信息和加密算法生成Token的工具
        JwtBuilder builder = Jwts.builder()
                //设置身份标志,就是一个客户端的唯一标记,如:可以使用用户的主键,客户端的ip或者是服务端生成的随机数据
                // .setId(id)
                //签发者
                // .setIssuer(iss)
                //携带的公开信息
                // .setSubject(claims.toString())
                //会覆盖上面设置元素的值
                .setClaims(claims)
                //签发时间,token生成时间
                .setIssuedAt(data)
                //设定密钥和算法
                .signWith(signatureAlgorithm, getSecretKey());
        //判断token存储的有效期
        if (ttlMillis >= 0) {
            //当前创建的时间 加存储时间
            long l = nowMillis + ttlMillis;
            //获取失效时间
            Date exp = new Date(l);
            //设置token失效时间
            builder.setExpiration(exp);
        }
        //生成token
        return builder.compact();
    }

    /**
     * 解析jwt字符串
     *
     * @param token 就是服务器为客户端生成的签名,就是token
     * @return
     */
    public static Claims analysisJWT(String token) {
        return Jwts.parser()
                .setSigningKey(getSecretKey())
                .parseClaimsJws(token)
                //就是获取token中记录的payload数据,即使payload中保存的所有claims
                .getBody();
    }
}
  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-04-09 18:57:31  更:2022-04-09 18:57:54 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 22:25:42-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码