做网站价钱,广州企业黄页大全,物联网开发用什么语言,网页搜索功能怎么实现前言
在B/S系统中#xff0c;登录功能通常都是基于Cookie 来实现的。当用户登录成功后#xff0c;一般会将登录状态记录到Session中#xff0c;或者是给用户签发一个 Token#xff0c;无论哪一种方式#xff0c;都需要在客户端保存一些信息(Session ID或Token)#xff0…前言
在B/S系统中登录功能通常都是基于Cookie 来实现的。当用户登录成功后一般会将登录状态记录到Session中或者是给用户签发一个 Token无论哪一种方式都需要在客户端保存一些信息(Session ID或Token)并要求客户端在之后的每次请求中携带它们。在这样的场景下使用Cookie无疑是最方便的因此我们一般都会将Session的ID或 Token保存到Cookie中当服务端收到请求后通过验证Cookie中的信息来判断用户是否登录。
单点登录(Single Sign On,SSO)是指在同一帐号平台下的多个应用系统中用户只需登录一次即可访问所有相互信任的应用系统。举例来说百度贴吧和百度地图是百度公司旗下的两个不同的应用系统如果用户在百度贴吧登录过之后当他访问百度地图时无需再次登录那么就说明百度贴吧和百度地图之间实现了单点登录。单点登录的本质就是在多个应用系统中共享登录状态。如果用户的登录状态是记录在Session 中的要实现共享登录状态就要先共享Session,比如可以将 Session序列化到Redis中让多个应用系统共享同一个Redis直接读取 Redis来获取 Session。当然仅此是不够的因为不同的应用系统有着不同的域名尽管Session 共享了但是由于Session ID是往往保存在浏览器Cookie中的因此存在作用或的限制无法跨域名传递也就是说当用户在app1.com中登录后SessionID仅在浏览器访问app1.com时才会自动在请求头中携带而当浏览器访问app2.com时Session ID是不会被带过去的。实现单点登录的关键在于如何让 Session ID(或Token)在多个域中共享。
实现方式一:父域 Cookie
在将具体实现之前我们先来聊一聊Cookie的作用域。Cookie 的作用域由 domain属性和path 属性共同决定。domain属性的有效值为当前域或其父域的域名/IP地址在Tomcat中domain属性默认为当前域的域名/IP地址。path属性的有效值是以“/”开头的路径在Tomcat 中path属性默认为当前Web应用的上下文路径。如果将Cookie的 domain属性设置为当前域的父域那么就认为它是父域Cookie。Cookie有一个特点即父域中的Cookie被子域所共享换言之子域会自动力继承父域中的Cookie。利用Cookie的这个特点不难想到将SessionID(或Token)保存到父域中不就行了。没错我们只需要将Cook ie 的 domain属性设置为父域的域名(主域名)同时将Cookie的path 属性设置为根路径这样所有的子域应用就都可以访问到这个Cookie了了。不过这要求应用系统的域名需建立在一个共同的主域名之下如tieba.baidu.com和map.baidu.com它们都建立在baidu.com这个主域名之下那么它们就可以通过这种方式来实现单点登录。 总结:此种实现方式比较简单但不支持跨主域名。
实现方式二:认证中心
我们可以部署一个认证中心认证中心就是一个专门负责处理登录请求的独立的 Web服务。用户统一在认证中心进行登录登录成功后认证中心记录用户的登录状态并将Token写入Cookie。(注意这个 Cookie是认证中心的应用系统是访问不到的)应用系统检查当前请求有没有 Token如果没有说明用户在当前系统中尚未登录那么就将页面面跳转至认证中心。由于这个操作会将认证中心的Cookie自动带过去因此认证中心能够根据Cookie知道用户是否已经登录过了。如果认证中心发现用户尚未登录则返回登录页面等待用户登录如果发现用户已经登录过了就不会让用户再次登录了而是会跳转回目标URL并在跳转前生成一个Token拼接在目标URL 的后面回传给目标应用系统。应用系统拿到Token之后还需要向认证中心确认下Token的合法性防止用户伪造。确认无误后应用系统记录用户的登录状态并将 Token写入Cookie然后给本次访问放行。(注意这个Cookie是当前应用系统的其他应用系统是访问不到的。)当用户再次访问当前应用系统时就会自动带上这个Token应用系统验证Token发现用户已登录于是就不会有认证中心什么事了。
实现方式三:LocalStorage 跨域
前面我们说实现单点登录的关键在于如何让 Session ID(或Token)在多个域中共享。父域Cookie 确实是一种不错的解决方案,但是不支持跨域。那么有没有什么奇淫技巧能够让Cookie 跨域传递呢?很遗憾浏览器对Cookie的跨域限制越来越严格。Chrome 浏览器还给Cookie新增了一个SameSite属性此举几乎禁止了一切跨域请求的Cookie传递(超链接除外)并且只有当使用HTTPs协议时才有可能被允许在AJAX跨域请求中接受服务器传来的Cookie。不过在前后端分离的情况下完全可以不使用Cookie,我们可以选择将Session ID(或Token)保存到浏览器的 LocalStorage中让前端在每次向后端发送请求时主动将LocalStorage的数据传递给服务端。这些都是由前端来控制的后端需要做的仅仅是在用户登录成功后将Session ID(或To oken)放在响应体中传递给前端。在这样的场景下单点登录完全可以在前端实现。前端拿到 Session ID(或Token)后除了将它写入自己的 LocalStorage中之外还可以通过特殊手段将它写入多个其他域下的LocalStorage 中。关键代码如下: 前端通过iframepostMessage()方式将同一份 Token写入到了多个域下的LocalStorage中前端每次在向后端发送请求之前都会主动从LocalStorage 中读取 Token并在请求中携带 这样就实现了同一份Token 被多个域所共享。 总结:此种实现方式完全由前端控制几乎不需要后端参与