最近在工作中碰到了session与cookie的问题,现在对碰到的问题进行回顾。
1.cookie机制是客户端保持会话的机制,将客户的会话信息保存在客户端。session机制是服务端保持会话的机制,是将客户的会话信息保存在服务端。
2.在采用cookie机制的时候,不需要服务端来配合,cookie可以独立的完成用户的会话跟踪
3.在采用session机制的时候,由于服务端存放session以后,必须将sessionId回传给客户端,客户端在后面请求必须携带sessionId,服务端端才可以判断用户。session保持会话时,客户端必须有一种方式存放sessionId,常用的就是写入客户端的cookie,这种情况下session就需要客户端cookie累配合保持会话,当然其他的也可以采用URL重写的方式每次发送请求的时候将sessionID携带URL或者表单中,通过URL而非cookie来实现会话跟踪。
4.tomcat的session的实现机制是采用服务端session+客户端cookie存放sessionId的方式来实现会话跟踪。如果浏览器禁用cookie,则这种方式的session会失效。
正常的session验证的流程应该是如下时序图:
浏览器一共发起两次请求,在第一次发起请求服务端验证通过后回写浏览器的cookie,写入sessionId,浏览器第二次访问的时候会自动携带cookie信息,服务器根据cookie信息完成隐式验证。
现在遇到一种这样的场景:
第三方网站的用户通过第三方的注册页面进行注册,第三方后台注册接口在处理注册请求同时,向认证服务器发送注册请求,完成在我方的注册操作,同时用户希望注册完成后就直接跳转到我方登录态的页面,不需要用户再手动登录一次。这种场景一般出现在跨域的登录和页面访问。
这样的场景中存在与正常的登录流程的一个区别是,浏览器在发起第一次的注册请求的时候,并不是直接请求的认证服务器,认证服务器在注册后,即使生成了tomcat session,但是并不能将sessionId写入浏览器的cookie中,原因在于浏览器并不是直接与认证服务器交互,中间是经过了一个第三方的服务器转发请求。
问题的产生:由于浏览器不直接与认证服务器交互,认证服务器产生session后,无法将sessionId写入浏览器的cookie中
一种解决的方案是:
在浏览器第一次发起注册请求,认证服务器完成注册,登录处理后,生成一个登录凭证,返回给浏览器,然后浏览携带登录凭证直接调用认证服务器进行用户身份验证(显式验证),验证通过后再生成tomcat session,回写sessionId到浏览器cookie中,然后浏览器再通过cookie发起需cookie方式认证的页面。
其与正常的session认证的流程是在注册登录请求与页面请求之间,加入了一个显式的sessionId验证用户身份的请求,通过一次显式的验证请求来回写cookie切换到隐式的身份验证。
其时序图如下:
其解决的思路是通过一次显式的验证(session+url携带sessionId)来过渡切换到隐式的登录(session+浏览器cookie携带sessionId)。