2019独角兽企业重金招聘Python工程师标准>>>

这篇主要说明基于Cookie的单点登录实现,以及Cookie的一些特性以及使用说明。

1、Cookie是什么,如何工作的

在程序中,会话跟踪是很重要的事情。理论上,一个用户的所有请求操作都应该属于同一个会话,而另一个用户的所有请求操作则应该属于另一个会话,二者不能混淆。例如,用户A在超市购买的任何商品都应该放在A的购物车内,不论是用户A什么时间购买的,这都是属于同一个会话的,不能放入用户B或用户C的购物车内,这不属于同一个会话。而Web应用程序是使用HTTP协议传输数据的。HTTP协议是无状态的协议。一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接。这就意味着服务器无法从连接上跟踪会话。即用户A购买了一件商品放入购物车内,当再次购买商品时服务器已经无法判断该购买行为是属于用户A的会话还是用户B的会话了。要跟踪该会话,必须引入一种机制。
      Cookie就是这样的一种机制。它可以弥补HTTP协议无状态的不足。在Session出现之前,基本上所有的网站都采用Cookie来跟踪会话。

Cookie意为“甜饼”,是由W3C组织提出,最早由Netscape社区发展的一种机制。目前Cookie已经成为标准,所有的主流浏览器如IE、Netscape、Firefox、Opera等都支持Cookie。

2、现实生活中类似于Cookie的举例

例如你所在的城市可能有很多便利店(web服务器),便利店一般都会举行一些活动,例如积满15次消费金额在20元以上,送毛绒公仔一只。但是客户(浏览器)特别多,便利店不可能每个都记住,于是便利店就制作一个卡片(Cookie)交给客户。之后每次客户来买东西的人时候就把卡片提交给便利店(web服务器),于是便利店就知道你目前的状态信息,这样就做到了跟踪会话。

从上面可以看出,Cookie是由浏览器管理的,web服务器将数据交给浏览器,浏览器可以把数据保存起来,等到下次访问的时候自动提交。

如上图中,在整个交互中的流程如下:

第一步:浏览器发送信息(例如:用户名密码)提交给服务器。

第二步:服务器接收到之后,发送一个命令给浏览器,告诉他你要把相关的信息存到cookie里面。

第三步:如果是零时性的就存于浏览器内存中,重启浏览器信息就消失了。

第四步:如果是需要存很久,例如两周之内自动登陆这种需求,则将信息存于硬盘上。

第五步:当在此访问浏览器时,则自动将cookie发送给服务器。

3、各浏览器都把Cookie放到了哪里

以Windows7为例:

IE浏览器:%APPDATA%\Microsoft\Windows\Cookies\ 目录中的xxx.txt文件 (IE浏览器分开存放的)。

火狐浏览器:%APPDATA%\Mozilla\Firefox\Profiles\ 目录中的xxx.default目录,名为cookies.sqlite的文件。

谷歌浏览器:%LOCALAPPDATA%\Google\Chrome\User Data\Default\ 目录中,名为Cookies的文件。

在IE浏览器中,IE将各个站点的Cookie分别保存为一个XXX.txt这样的纯文本文件(文件个数可能很多,但文件大小都较小);而Firefox和Chrome是将所有的Cookie都保存在一个文件中(文件大小较大),该文件的格式为SQLite3数据库格式的文件。

4、实际开发项目中如何使用代码操作Cookie

在Java中,Web项目提供了一个类:javax.servlet.http.Cookie 该类就与Cookie对应。下面给出Servlet中操作Cookie示例代码:

package com.csdn.cas;import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class LoginServlet extends HttpServlet {private static final long serialVersionUID = 1L;@Overridepublic void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 获取请求参数String userName = req.getParameter("userName");String passwd = req.getParameter("passwd");// 创建cookie对象Cookie userInfoCookie = new Cookie("userInfo", userName + ":" + passwd);// 返回给浏览器的数据中添加cookie信息resp.addCookie(userInfoCookie);}
}

上面就是简单的操作cookie的代码,我们将这个servlet部署到tomcat中,使用谷歌,并观察相关的cookie信息(使用F12,有调试工具)。

观察第一次的访问情况,在响应头里面多出来一个Set-Cookie:的东东,浏览器就根据这个这个cookie信息保留了下来。

当再一次访问这个网站时,则请求头中多了第一次返回的Cookie信息,响应中之所以还有Set-Cookie,是因为我们访问的是同一个代码。

如果你把浏览器关了,在访问这个地址,那么请求中是不会带有cookie信息的,因为浏览器只是零时性的将数据保存在内存中。如果需要保存在硬盘上则需要特殊处理。

5、Cookie的特性

5.1、Cookie不能跨域

例如:你访问www.baidu.com,百度给你发了一个cookie,你在访问www.google.com你是不能把百度发给你的cookie带到谷歌的服务器上的。

需要特别注意的是:images.google.com与www.google.com同属于google,但是他们的域名不一样,二者同样也不能操作彼此的Cookie,浏览器在访问的时候,会根据访问地址自动携带相关域名的cookie过去。

注意:有时候你会发现有些特殊的网站,类似你登录了www.google.com但是你当问images.google.com时,www.google.com的cookie被带到了images.google.com,这是因为做了特殊的处理,下面会详细说。

5.2、其他相关特性请参照博客

传送门:http://blog.csdn.net/fangaoxin/article/details/6952954/

6、利用Cookie的特性实现单点登录的原理

上图就是一个利用cookie做单点登录的原理图,案例为用户dgh(密码123)登录www.qiandu.com,之后又登录mail.qiandu.com。流程如下:

第一步:用户输入用户名/密码(dgh/123)登录到www.qiandu.com。

第二步:www.qiandu.com处理登录逻辑,并且将用户信息通过cookie的方式返回到客户端(最好加密用户信息)。

第三步:用户访问mail.qiandu.com,浏览器自动将用户信息携带到mail.qiandu.com,通过过滤器(filter)处理用户的登录请求。

第四步:过滤器从cookie中获取用户信息,登录,返回用户访问界面。这样用户就只登录一次,就访问了两个网站了。

7、Cookie实现单点登录的代码实现

1、首先是一个登录的Servlet,简单实现,只要用户名密码相同则登录成功,并将信息写到cookie中。

package com.csdn.cas;import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;public class LoginServlet extends HttpServlet {private static final long serialVersionUID = 1L;@Overridepublic void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 获取请求参数String userName = req.getParameter("userName");String passwd = req.getParameter("passwd");resp.setCharacterEncoding("UTF-8");resp.setContentType("text/html;charset=UTF-8");HttpSession session = req.getSession();// 只有用户名与密码相同,则登录成功if(userName.equals(passwd)){// 创建cookie对象Cookie userInfoCookie = new Cookie("userInfo", userName + ":" + passwd);// 这里很重要,不设置无法夸子域 这里最好以 .开头,例如.qiandu.com// 谷歌浏览器自动给他添加了.userInfoCookie.setDomain("qiandu.com");// 返回给浏览器的数据中添加cookie信息resp.addCookie(userInfoCookie);session.setAttribute("userName", userName + ",登录成功");}else {session.setAttribute("userName", userName + ",登录失败");}req.getRequestDispatcher("/index.jsp").forward(req, resp);}
}

2、写一个Filter,过滤处理所有的请求,如果是登录请求则到登录页,否则尝试登陆。

package com.csdn.cas;import java.io.IOException;import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;public class LoginFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException { }@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {HttpServletRequest req = (HttpServletRequest)request ;HttpServletResponse resp = (HttpServletResponse) response ;Cookie[] cookies = req.getCookies();resp.setCharacterEncoding("UTF-8");resp.setContentType("text/html;charset=UTF-8");HttpSession session = req.getSession();Object userInfo = session.getAttribute("userName");if(userInfo == null){ // 没登录if(cookies != null){ // 有cookiefor(Cookie cookie : cookies){if("userInfo".equals(cookie.getName())){String[] value = cookie.getValue().split(":");String userName = value[0];String passwd = value[1];// 只有用户名与密码相同,则登录成功if(userName.equals(passwd)){// 创建cookie对象session.setAttribute("userName", userName + ",从filter登录成功");}else {session.setAttribute("userName", userName + ",从filter登录失败");}}}} else {// 这里应该跳转到登录页面}}chain.doFilter(request, response);}@Overridepublic void destroy() {  }
}

3、index.jsp页面就展示登录用户用户名,如果没有登录就显示null

<html>
<body><h1>Hello !</h1><h2><%=session.getAttribute("userName")%></h2>
</body>
</html>

注意:

上面说过cookie是不能跨域的,通过特殊设置setDomain()可以做到夸同一个大域下的两个子域。例如,www.qiandu.com与mail.qiandu.com这是两个域,但是他们都是qiandu.com下的两个子域,则可以通过设置cookie.setDomain("qiandu.com")从而达到夸域。但是对于www.baidu.com与www.google.com就没得办法了。

8、测试Cookie的单点登录

修改windows的hosts文件,添加如下内容:

测试步骤:

第一步:启动服务器,通过www.qiandu.com访问服务,显示登陆失败

第二步:通过get方式登录:http://www.qiandu.com/login?userName=dgh&passwd=dgh

第三步:登录http://mail.qiandu.com,发现第一次登陆mail.qiandu.com用户名密码就被cookie带过来了。

然后页面显示:

注意:为什么www.qiandu.com的cookie能带到mail.qiandu.com呢?我们从浏览器中查看cookie信息即可得知,域是www.qiandu.com与mail.qiandu.com的公共部分,所以浏览器认为,他们是一起的,cookie交流是安全的。而且我代码中写的是qiandu.com,浏览器自动在前面加了一个点

案例代码:http://download.csdn.net/detail/readiay/9654716

CAS统一认证的原理:http://blog.csdn.net/readiay/article/details/52856510

转载于:https://my.oschina.net/iyinghui/blog/1525306

【No.1】基于Cookie的单点登录(SSO)相关推荐

  1. 基于Cookie的单点登录(SSO)系统介绍

    基于Cookie的单点登录(SSO)系统介绍 SSO的概念: 单点登录SSO(Single Sign-On)是身份管理中的一部分.SSO的一种较为通俗的定义是:SSO是指访问同一服务器不同应用中的受保 ...

  2. 基于.Net的单点登录(SSO)解决方案

    基于.Net的单点登录(SSO)解决方案 前些天一位朋友要我帮忙做一单点登录,其实这个概念早已耳熟能详,但实际应用很少,难得最近轻闲,于是决定通过本文来详细描述一个SSO解决方案,希望对大家有所帮助. ...

  3. 基于云端的通用权限管理系统,SAAS服务,基于SAAS的权限管理,基于SAAS的单点登录SSO,企业单点登录,企业系统监控,企业授权认证中心...

    基于云端的通用权限管理系统 SAAS服务 基于SAAS的权限管理 基于SAAS的单点登录SSO 基于.Net的SSO,单点登录系统,提供SAAS服务 基于Extjs 4.2 的企业信息管理系统 基于E ...

  4. SSO单点登录学习总结(2)——基于Cookie+fliter单点登录实例

    1.使用Cookie解决单点登录 技术点: 1.设置Cookie的路径为setPath("/").即Tomcat的目录下都有效 2.设置Cookie的域setDomain(&quo ...

  5. SSO单点登录-基于cookie的单点登录

    1.概述 单点登录(Single-Sign-On),简称SSO,它的解释为:在多个应用系统中,只要登陆一次,便可以访问其它相互信任的系统.早期系统由于只有一个服务,因此只需要登录一次,就可以访问系统的 ...

  6. 基于OIDC实现单点登录SSO、第三方登录

    OIDC联合身份认证机制 背景概念 1 OIDC身份认证协议 2 基于OIDC实现SSO 2.1 统一登录 2.1.1 流程 2.1.2 RP相关接口 2.1.3 OP相关接口 2.2 统一登出 2. ...

  7. 浅谈单点登录SSO实现方案 | StartDT Tech Lab 06

    写在前面 这是奇点云全新技术专栏「StartDT Tech Lab」的第6期. 在这里,我们聚焦数据技术,分享方法论与实战.一线的项目经历,丰富的实践经验,真实的总结体会-滑到文末,可以看到我们的往期 ...

  8. 基于JSON Web Tokens的单点登录(SSO)或通行证(Passport)系统方案

    首先简要介绍一下什么JWT(JSON Web Token). JWT是一种开放的,工业标准的规范,用于在两个应用之间安全地传输信息. JWT由3个部分组成,分别是头部.载荷.签名. 头部部分 {   ...

  9. cookie实现单点登录

    前言 在单点登录方案设计一篇中,我们谈到了目前市面上常用的一些单点登录方案的实现,关于单点登录,只需要把握一个核心的要点即可,那就是:一处登录,处处登录,登录之后,即同域下其他各个系统都能统一拿到用户 ...

最新文章

  1. 深入理解计算机系统 -资料整理 高清中文版_在所不辞的博客-CSDN博客_深入理解计算机系统第四版pdf
  2. OSChina 周一乱弹 ——渴望咪咪还是渴望力量,都能给你
  3. angluar bulid 的时候报错
  4. vs联合torch,ZED相机api,opencv建立C++项目
  5. php中如何配置环境变量,如何配置phpstorm环境变量如何配置phpstorm环境变量
  6. 收藏 | 深度学习图像分类任务中那些不得不看的技巧总结
  7. 应用Canary文件类型阻击勒索软件
  8. 浅谈局部敏感哈希LSH
  9. c语言有趣小程序,c语言小程序代码大全(9个经典的C语言小程序)
  10. JSP程序设计之(1)Tomcat安装及环境变量配置
  11. linux搭建windows无盘系统,linux下无盘系统的安装
  12. 大数据下的数据分析平台架构
  13. Typora极简教程
  14. 三星高价卖苹果iPhone X OLED屏幕, 苹果或寻新队友
  15. ubuntu18.04 安装Pangolin
  16. 前端工作过程遇到的问题总结(九)
  17. MongoDB 数据库(一):MongoDB的介绍与安装
  18. 湖北大学计算机考研参考书,湖北大学2018考研专业课参考书
  19. kafka: dial tcp: lookup xxxx(domain): no such host
  20. 计算机与制药工程论文,制药工程论文范文

热门文章

  1. IOS6.0与IOS7.0屏幕适配
  2. phpcms能做什么呢?有什么作用呢?
  3. SCCM 2012 R2 从入门到精通 Part8 软件部署
  4. ASP.NET中的HTTP模块和处理程序
  5. linux netperf的安装
  6. 给一些技术类的链接(转)
  7. linux 文件查找帮助命令 , 查看网络链接信息, 历史命令
  8. Exchange-统计一年新增的邮箱数
  9. 大型云原生项目在数字化企业落地过程解密 1
  10. WPF 3D模型的一个扩展方法