澳门皇冠金沙网站▎在线官网
做最好的网站

使用redis管理用户登录会话的方法澳门皇冠金沙网

2020-01-09 作者:网络服务   |   浏览(149)

登录和cookie缓存

一:理解单系统登录的原理及实现?

对于用来登录的cookie,有两种常见的方法可以将登录信息存储在cookie里面:一种是签名cookie,另一种是令牌cookie。

web应用采用的 browser/server 架构的,http是无状态协议的,也就是说用户从A页面跳转到B页面会发起http请求,当服务器返回响应后,当用户A继续访问其他页面的时候,服务器端无法获知该状态,因此会使用cookie/session来记录用户状态的。

签名cookie通常会存储用户名,可能还有用户ID、用户最后一次成功登陆的时间,以及网站觉得有用的其他任何信息。除了用户的相关信息外,签名cookie还包含一个签名,服务器可以使用这个签名来验证发送的信息是否未经改动。

session认证状态的基本原理:当客户端向服务器端请求时,会创建一个session标识存在客户端的cookie当中,每次请求的时候会将该标识随cookie一起发送到服务器端,服务器端会首先检查这个客户端的请求里面是否包含了一个session的标识,如果已经包含了,那么服务器端就会根据该session标识来判断用户的状态,否则的话,服务器端会创建一个新的session标识传给客户端的cookie当中,以后每次客户端请求的时候,会从cookie中获取该标识传递过去。

令牌cookie会在cookie里面存储一串随机字节作为令牌,服务器可以根据令牌在数据库中查找令牌的拥有者。下表展示了签名cookie和令牌cookie的优点与缺点。

二:理解单点登录的原理?

cookie类型

上面使用session/cookie 可以实现单个系统的登录,那如果是多个系统的话,怎么办?难道需要用户一个个去登录? 一个个去注销?我们需要做的是,无论系统有多少个,我们只需要登录一次就够了,其他的相关的系统都可以登录/注销一次即可。

优点

单系统登录解决方案的核心是cookie,cookie会携带服务器端返回的sessionId, 在浏览器与服务器端维护会话状态。但是我们知道cookie是有限制的,cookie有域的概念,浏览器发送http请求时会自动匹配该本站点的cookie域。而不是所有的cookie。

缺点

那么既然这样,我们很容易想到的是,我们可以把所有子系统的域名都放在一个顶级域名下不就可以了?比如 "*.taobao.com",然后将他们的cookie域设置为 "taobao.com", 但是这种并不好:

签名cookie 验证cookie所需的一切信息都存储在cookie里面。cookie可以包含额外的信息,并且对这些信息进行签名也很容易 正确地处理签名很难。很容易忘记对数据进行签名,或者忘记验证数据的签名,从而造成安全漏洞 令牌cookie 添加信息非常容易。cookie的体积非常小,因此移动端和速度较慢的客户端可以更快地发送请求 需要在服务器中存储更多信息。如果使用的是关系数据库,那么载入和存储cookie的代价可能会更高

第一:因为所有系统的域名需要统一,比如淘宝和天猫的域名就不相同;
第二:应用群各个系统所使用的技术需要相同,比如tomcat服务器叫JESSIONID, 其他的服务器可能不叫这个标识。
第三:cookie的安全性不高的。

下面是用java写的一个例子

因此我们需要一种全新的方式来实现多系统应用群的登录,这就是单点登录。

import java.util.ArrayList;import java.util.Set;import redis.clients.jedis.Jedis;public class Login { public String checkToken(Jedis conn,String token){ return conn.hget("login:", token); } public void updateToken(Jedis conn,String token,String user,String item){ long time=System.currentTimeMillis()/1000; conn.hset("login:", token, user);//维持令牌与用户之间的映射 conn.zadd("recent:", time, token);//保存令牌最后一次出现的时间 if(item!=null){ conn.zadd("viewd:"+token, time, item);//根据这个令牌来设置该用户在这个时间戳访问的商品名字 conn.zremrangeByRank("viewd:"+token, 0, -26);//移除就的用户记录,只保留用户浏览过的25个商品。 conn.zincrby("viewd:", -1, item); } } public class CleanSessionsThread extends Thread{ private Jedis conn; private int limit; private boolean quit; public CleanSessionsThread(int limit) { // TODO Auto-generated constructor stub this.conn=new Jedis("localhost"); conn.select(15); this.limit=limit; } public void quit(){ quit=true; } @Override public void run() { // TODO Auto-generated method stub while(!quit){ long size=conn.zcard("recent:");//依据登录时间确定在线人数 if(size=limit){ try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } }else{ long endIndex=Math.min(size-limit,100); SetString tokensSet=conn.zrange("recent:", 0, endIndex-1); String[] tokens=tokensSet.toArray(new String[tokensSet.size()]); ArrayListString sessionKeys=new ArrayList(); for(String token:tokens){ sessionKeys.add("viewd:"+token); } conn.del(sessionKeys.toArray(new String[sessionKeys.size()])); conn.hdel("login:", tokens); conn.zrem("recent:", tokens); } } } }}

什么是单点登录?单点登录的全称是 Single Sign On , 在多个系统中只要登录一次,便可以在其他所有系统中得到授权而无需再次登录。

以上这篇使用redis管理用户登录会话的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

SSO有一个独立的认证中心,认证中心它可以接受用户的用户名密码等安全信息,其他的地方不接受登录入口,只接受认证中心的间接授权,间接授权它是通过令牌实现的。授权令牌作为参数会发送到各个子系统,子系统拿到令牌,因此会得到了授权,因此就可以创建了局部的会话。局部会话和单系统登录的原理很类似的。

下面我们来打个比方理解单点登录的基本原理:

第一步:我想登录A系统,A系统发现用户未登录,因此我们需要他们跳转到SSO认证中心(且将自己请求的地址作为参数传递过去)。SSO认证中心发现未登录,会将用户引导到登录页面。

第二步:用户输入用户名和密码提交申请登录,SSO认证中心会检测用户名和密码信息,如果用户名和密码正确的话,那么用户和SSO认证中心之间会创建一个局部会话,并且创建一个授权令牌。sso认证中心会带着该令牌跳转到A系统那个请求的地址去。

第三步:A系统会检测该令牌,如果有效的话,就会跳到用户输入的地址页面去,否则,还是返回登录页面,提示错误信息。

第四步:用户访问系统B,系统B发现用户未登录,会跳转到SSO认证中心(将自己请求的地址作为参数传递过去),sso认证中心发现用户已经登录了,会跳转回系统B的那个地址去,并带上令牌,系统B拿到令牌,就会去sso认证中心去校验该令牌是否有效。
如果有效的话,说明认证成功了,就会跳转到系统B访问地址的页面上去。

用户现在已经登录成功了,sso认证中心会与各个子系统建立会话,用户与sso认证中心建立的会话被称为全局会话,用户与各个
子系统建立的会话被称为局部会话,局部会话建立之后,用户访问子系统资源后就不会再通过sso认证中心了。


三:什么是JSON Web Token?

JSON Web Token 是一个开放标准协议,它定义了一种紧凑和自包含的方式,它用于各方之间作为JSON对象安全地传输信息。

它有如下优点:

1. 可以适用于分布式的单点登录场景。
2. 可以使用跨域认证解决方案。
3. jwt实现自动刷新token的方案。

JSON Web Token,它定义了一种紧凑和自包含的方式,如何理解紧凑和自包含呢?

紧凑:就是说这个数据量比较少,并且能通过url参数,http请求提交的数据以及http header的方式来传递。
自包含:这个串可以包含很多信息,比如用户id,订单号id等,如果其他人拿到该信息,就可以拿到关键业务信息。

3.1)JWT的基本原理,基本流程如下:

  1. 客户端使用账号和密码请求登录接口。
  2. 登录成功后服务器使用签名密钥生成JWT,然后返回JWT给客户端。
  3. 客户端再次向服务端请求其他接口时会带上JWT。
  4. 服务器接收到JWT后验证签名的有效性,对客户端做出相应的响应。

3.2)JWT与session的区别?

session是基于cookie来传输的,session信息是存储在服务器端中,客户端向服务器端发请求时,服务器端会返回一个jessionId给客户端中的cookie中,以后每次请求都会从cookie中的jessionid传递过去,服务器通过cookie中的sessionid获取到当前会话的用户,对于单系统来讲这是没有问题的,但是对于多个系统的话就涉及到session如何共享的问题了,并且随着认证用户增多的话,session会占用大量服务器内存。

JWT是存储在客户端的,服务器端不需要存储JWT,JWT含有用户id,服务器拿到jwt验证后就可以拿到用户信息了,jwt是无状态的,它不与任何机器绑定的,只要签名密钥足够的安全就能保证jwt的可靠性。

3.3)JWT中的token与session中的token安全性比较

session 中安全性问题:

服务器端执行session机制的时候会生成session的口令,在Tomcat服务器中,默认会采用 jsessionid 这个值,但是在其他服务器上会有所不同,比如Connect默认会叫 connect_uid, 我们一般把一些敏感的信息放在cookie中是不可取的,但是将口令放在cookie中还是可以的,如果口令被篡改了的话,就丢失了映射关系,也无法修改服务器端存在的数据,并且session的有效期一般为20/30分钟,如果在该时间之内客户端和服务器端没有产生任何交互,服务器端会自动将session自动清空,因此session中想要维护用户一直登陆的状态的话,需要客户端每隔20分钟使用setInterval自动发一个请求给服务器端,这样的话,前后端就有交互,所以就可以一直保持登陆状态。否则的话,每次20分钟后,登陆状态就会失效,每隔20分钟用户需要重新登录,用户体验将会变得不好。session这样做的最主要的是为了安全性考虑,有效期的时间非常短,防止黑客攻击。

JWT方案中安全性问题

jwt是存储在客户端的,服务器端不需要存储jwt的,客户端每次发送请求时会携带该token,然后到服务器端会验证token是否正确,是否过期了,然后会通过解码出携带的用户的信息的,但是如果token在传输的过程中被攻击者截取了的话,那么对方就可以伪造请求,利用窃取到的token模拟正常请求,实现用户的正常操作,而服务器端完全不知道,因为JWT在服务器端是无状态的,且服务器端不存储jwt的。其实jwt解决的问题是认证和授权的问题,对于安全性的话,还是建议对外公布的接口使用https.

四:理解JWT的基本数据结构

基本的JWT的数据结构是如下这样的:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoia29uZ3poaSIsImlhdCI6MTU0Mzc1MzczNX0.h1XmQo017udxlFsH-8US9Lg8dJ0IDsSbRbjEN5Nq0l4

如上它是由三部分组成的,中间使用 . 分割成三个部分,它是有 Header, PayLoad,Signature组成的。
如:Header.Payload.Signature

4.1 Header

澳门皇冠金沙网站,在线官网,Header部分是一个JSON对象,描述JWT的元数据,一般是如下的样子:

{  "typ": "JWT",  "alg": "HS256"}

如上json代码,alg属性表示签名的算法,默认是 HMAC SHA256 (缩写为:HS256); typ属性表示这个令牌的类型为JWT. 最后将上面的JSON对象使用 Base64URL的算法转成字符串。
我们可以使用在线的base64编码转下(http://tool.oschina.net/encrypt?type=3),如下所示:

澳门皇冠金沙网站,在线官网 1

如上 alg 部分,默认加密的算法是 HMAC SHA256, 当然我们也可以选择下面的加密算法,加密算法有如下:

澳门皇冠金沙网站,在线官网 2

4.2 Payload

Payload部分也是一个JSON对象,用来存放实际需要传递的数据,官方提供了7个字段,如下:

澳门皇冠金沙网站,在线官网 3

iss: 签发人exp (expiration time): 过期时间sub : 主题aud : 受众nbf (Not Before): 生效时间iat (Issued At): 签发时间jti : 编号

澳门皇冠金沙网站,在线官网 4

payload的中文含义是载荷,它可以理解为存放有效信息的地方。这些有效信息一般包含如下三个部分:

4.2.1)标准中注册的声明:(如上就是官方提供的7个字段)。

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

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

那么定义一个简单的 payload 可以如下结构:

本文由澳门皇冠金沙网站发布于网络服务,转载请注明出处:使用redis管理用户登录会话的方法澳门皇冠金沙网

关键词: