跨域用户信息判断Token、seeion、jwt

本文介绍了单点登录(SSO)、三方登录、Session跨域、SpringSession共享、NginxSession管理和Token机制,特别是JWT(JSON Web Token)的工作原理与使用。内容涵盖不同场景下的会话管理解决方案,包括如何实现跨域Session、集群环境下的Session共享以及基于Token的身份验证,提供了JWT的创建和解析示例。
摘要由CSDN通过智能技术生成

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

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

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

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();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值