面试被问了一百遍的同源策略,所以到底这个同源策略到底有个什么用,为什么在面试的时候会一直被问到,什么是同源策略,同源策略可以作用在什么场景,在本文给大家来个浅析,希望大家下次再遇到《什么是同源策略》这个面试题的时候,不要只会回答理论层次的答案,可以适当引导面试官,到同源策略的应用场景上,给自己的面试加分。
什么是同源策略
理论性的知识大家简单的过一遍,熟读于心的朋友直接跳过。
同源策略(Same-Origin Policy)是浏览器的一种安全策略,用于限制一个网页中的文档或脚本只能与来自相同源(相同的协议、域名和端口号)的资源进行交互。这个策略的存在是为了防止恶意网站通过脚本等手段获取用户的敏感信息,保护用户的隐私和安全。
同源策略主要限制以下几个方面的操作:
- Cookie、LocalStorage 和 IndexDB 等存储性的内容:同源策略要求网页只能访问与其来源相同域的 Cookie、LocalStorage 和 IndexDB 等存储内容。
- DOM(文档对象模型)操作:一个网页只能操作属于自己的窗口中的 DOM,不能操作其他窗口的 DOM。这意味着跨域的网页无法通过常规的 DOM 方法获取或修改其他网页的内容。
- Ajax 请求:XMLHttpRequest 被同源策略限制,因此,通过 XMLHttpRequest 发起的 Ajax 请求只能向同一域中的资源发出。
- 跨窗口通信:通过 postMessage 进行的跨窗口通信也受到同源策略的限制,消息只能被发送到同一域中的窗口。
这些限制有助于防止恶意网站利用用户浏览器执行恶意操作,如跨站脚本攻击(XSS)或跨站请求伪造(CSRF)。虽然同源策略对于安全至关重要,但也导致了一些开发上的挑战,因为开发者需要寻找其他方法来进行跨域通信和资源共享,如使用 JSONP、CORS(跨域资源共享)等技术。
从以上方面来看,同源策略是出于对网站的安全
同源网站
和同源相反的是跨域
,也可以说是不同源。
同源是指两个网页具有相同的协议(如http或https),相同的域名和相同的端口号。
如果两个网页的协议、域名和端口号都相同,它们就被认为是同源的
。同源策略是一个Web浏览器的安全特性,它限制一个网页从一个源加载的资源如JavaScript、CSS或Ajax请求等,只有当请求的资源与原始页面具有相同的源时,浏览器才会允许加载。
小总结:同源网站可以共享cookie等数据,那这个东西有什么用,如果我现在有不同的几个客户端,它们都挂到同一个域名下面,它们是同源的,那如果我将登录信息存储到一个它们三个客户端,三个客户端登录验证的时候,都能共享登录信息,只需要一个客户端登录,其他客户端也能拿到登录信息,即可不用重新登录,这个就是我要说的同源的场景------单点登录。
什么是单点登录
单点登录(Single Sign-On,简称 SSO)是一种身份验证和访问控制的机制,允许用户在多个应用程序或系统中使用一组凭据(例如用户名和密码)进行登录,而无需在每个系统中单独进行身份验证。
SSO 的主要目标是提高用户体验、减少密码疲劳,同时提高整个系统的安全性。在实施 SSO 时,用户只需登录一次,然后就可以无缝地访问多个相互信任的应用程序或服务,而无需再次输入凭据。
单点登录实现方式
- 基于cookie的SSO
- 用户在登录一个系统后,服务器为其颁发一个包含身份信息的加密 Cookie。
- 其他系统可以通过共享相同的域和路径来访问这个 Cookie。
- 当用户尝试访问其他系统时,这些系统会检查是否存在有效的 Cookie,如果存在则认为用户已经登录。
- 基于Token的SSO
- 用户在登录后,认证服务器颁发一个令牌(Token)给用户。
- 用户在访问其他系统时,将这个令牌发送给其他系统的认证服务器。
- 其他系统的认证服务器验证令牌的有效性,如果有效则允许用户访问。
-
基于第三方的SSO
使用标准的身份提供者(如 OAuth、OpenID Connect 等)进行身份验证。 用户在一个系统中登录后,可以在受信任的系统中无缝地访问资源,而不需要重新登录。
实现 SSO 需要系统之间有一定程度的信任,并通常涉及到标准协议和技术。例如,OAuth 和 OpenID Connect 是常用于实现 SSO 的标准协议,它们提供了安全的身份验证和授权机制。
cookie和token的单点登录
他们都有一个共通的特点,无论是什么实现方式,你的token或者cookie(登录信息)的来源只有一个,单点登录的特点就是多个系统之间公用一个登录信息,以减少重复登录的密码疲劳,cookie和token的实现方式比较相似,用户访问系统的时候,会访问同源系统查看是否已存在cookie,如果存在,则把登录信息发送到登录服务,登录服务验证已登录后,则绕过密码验证。
Cookie如何实现单点登录
这是我花的一个草图,大家可以带着往下看
我们起了一个8080的客户端,登录的时候,登录请求会返回一个setcookie,将cookie从服务端发送到客户端,服务器向浏览器发送响应时,可以通过设置HTTP头中的Set-Cookie
字段来在浏览器端存储Cookie。
可以到F12控制台,查看cookie
为了验证cookie的共享,我在本地起了另外一个端口为8000的客户端,从下图可以看出,ip相同,策略相同,端口不同,符合同源策略
我们打开控制台可以看出,都有一个Jsessionid,在这里可以看出cookie已经是共享了。
如此一来,8000客户端发送请求的时候,就会自动携带上cookie(一般情况下,当浏览器发起对同一域名的请求时,会自动携带该域名下的所有符合路径和过期时间条件的 Cookie。这是浏览器的默认行为,符合同源策略),如果要实现单点登录,就可以从这一点入手
现在的8000和8080客户端都是携带了cookie,如果我们把登录信息放到了cookie中,那就可以简单的实现单点登录了,当然还需要一个前提,就是他们访问的服务是同一个服务,意思也就是需要有一个服务去认证他们这个cookie的登录信息是同一个登录信息。