iframe页面总是提示需要重新登录怎么办
原文链接:iframe页面二次登录问题
生产问题
问题背景
由于历史原因,公司内部系统有一些页面是基于iframe嵌入的其他系统的页面,之前一直运行正常,最近不知什么原因接连出现访问所有iframe页面时提示需要登录的情况,并且点击iframe页面的登录按钮时会出现页面闪一下,没有任何跳转的现象。

问题显而易见,怎么解决呢?透过现象看本质,旁边业务还在催问什么时候能恢复,只能硬着头皮一步步分析着看。

首先,这些系统都接入了公司内部的sso服务,主体系统A已经成功登录的情况下,内嵌系统B还需要二次登录,肯定是相关鉴权未通过。
而整个鉴权信息都是基于Cookie机制来完成的,所以借此机会先回顾一下Cookie相关知识。
原因定位
跟踪网络请求发现,当请求内嵌页面时,首先会发起SSO认证请求https://sso.xxx.com/authentication/login?sevice=http://b.xxx.com,这个请求的scheme是HTTPS,而主系统A没有升级HTTPS, 所以B系统发起SSO认证时属于cross-site情形,无法携带此前生成的用户身份Cookie信息,用户鉴权失败。


当点击内嵌页面中的登录按钮时,由于此时发起的请求仍然是cross-site的,所以Cookie始终无法写入,就会出现页面闪一下,但并未登录的情况。

Cookie
HTTP Cookie是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器发起请求时被携带并发送到服务器上。
Cookie主要用于以下三个方面:
- 会话状态管理,如用户登录状态、购物车、游戏分数等。
- 个性化设置,如用户自定义设置,主题等。
- 浏览器行为跟踪,如跟踪分析用户行为等。
第三方Cookie
Cookie与域关联。如果此域与您所在页面的域相同,则该Cookie称为第一方Cookie(first-party cookie)。如果域不同,则它是第三方Cookie(thirty-patry cookie)。第三方Cookie是由第三方网站引导发出的,可以用于CSRF攻击以及用户行为追踪。
限制访问Cookie
通过以下方式可以确保Cookie被安全发送,不会被意外的参与者或脚本访问:
Secure属性:标记为Secure的Cookie只能通过被HTTPS协议加密过的请求发送给服务端,可以借此来预防中间人攻击从 Chrome 52 和 Firefox 52 开始,不安全的站点(
http:)无法使用Cookie的Secure标记。HttpOnly属性:JavaScript的Document.cookieAPI无法访问带有HttpOnly属性的Cookie,此类Cookie仅作用于服务器。例如,持久化服务器会话的Cookie不需要对JavaScript可用,因此可以设置HttpOnly属性。可以借此来缓解XSS攻击。
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly
Cookie作用域
通过Domain和Path标识来定义Cookie的作用域:即允许Cookie应该发送给哪些URL。
Domain属性
指定哪些主机可以接受Cookie。默认为origin,不包含子域名。如果指定了Domain,则一般包含子域名。
当前大多数浏览器遵循 RFC 6265,设置 Domain 时 不需要加前导点。浏览器不遵循该规范,则需要加前导点,例如:Domain=.mozilla.org
Path属性
指定主机下哪些路径可以接受Cookie(该URL路径必须存在于请求URL中)。以字符%X2F("/")作为路径分隔符,子路径也会被匹配。
例如,设置Path=/docs,以下地址都会匹配:
- /docs
- /docs/web/
- /docs/web/HTTP
SameSite属性
SameSite属性允许服务器要求某个Cookie在跨站请求时不会被发送,从而可以阻止跨站请求伪造攻击(CSRF)。
Set-Cookie: key=value; SameSite=Strict
SameSite取值有以下三种:
None:浏览器会在同站请求、跨站请求下继续发送Cookie,不区分大小写。大多数网站已经将
SameSite的默认值设置为Lax,此时如果网站想要关闭SameSite属性,必须在将SameSite属性设置为None的同时设置Secure属性,否则无效。
// 该设置无效
Set-Cookie: widget_session=abc123; SameSite=None
// 有效设置
Set-Cookie: widget_session=abc123; SameSite=None; Secure
Strict浏览器只在访问相同站点时发送Cookie。Lax:与Strict类似,但用户从外部站点导航至目标网址的Get请求除外(链接、预加载请求以及GET表单)。
| 请求类型 | 示例 | 正常情况 | Lax |
|---|---|---|---|
| 链接 | <a href="..."></a> |
发送 Cookie | 发送 Cookie |
| 预加载 | <link rel="prerender" href="..."/> |
发送 Cookie | 发送 Cookie |
| GET 表单 | <form method="GET" action="..."> |
发送 Cookie | 发送 Cookie |
| POST 表单 | <form method="POST" action="..."> |
发送 Cookie | 不发送 |
| iframe | <iframe src="..."></iframe> |
发送 Cookie | 不发送 |
| AJAX | $.get("...") |
发送 Cookie | 不发送 |
| Image | <img src="..."> |
发送 Cookie | 不发送 |
same-origin和same-site
同源(same-origin)、同站点(same-site)是两个随处可见的概念,但是这两个概念经常容易被混淆。
Origin
首先来看一下origin的定义是什么。scheme + hostname + port构成的整体叫做origin,例如https://www.example.com/443/foo的origin是https://www.example.com/443。

具有相同的scheme、hostname以及port的站点被视为同源站点,否则视为跨域(cross-origin)站点.
Site
学习site之前,先来了解一下什么是TLD、eTLD。
TLD
TLD全称叫做顶级域名(Top-Level-Domain),比如我们经常看到的com、cn、io之类的,都属于顶级域名。
TLD有一个记录列表,这个列表叫做Root Zone Database,里面记录了所有的顶级域名。需要注意的是,顶级域名不一定都是单词很短且只有一级的域名。

如上图,TLD和它之前部分的域构成的整体叫做"site",比如https://www.example.com:443/foo ,"site" 是example.com。
eTLD
除了顶级域名之外,还有一种叫做eTLD(effective Top-Level-Domain)的东西,它表示的是有效顶级域名。
例如.io是一个TLD,而像.github.io,是一个开放给用户的用于搭建个人网站的一个域。比如现在有以下三个网站:
http://zhangsan.github.io
http://lisi.github.io
http://wangwu.github.io
我们判断是否是同一个站点,通常是采用顶级域名+二级域名来判断,这里如果直接用.io这个TLD来识别,就会认为这三个网站是同一个站点,Cookie可以共享。
显然这是有问题的,因此需要引入eTLD的概念,将.io与github合起来的.github.io注册为一个"effective TLDs"。将eTLD+1整体视为网站的站点名称,这样一来,上述三个网址表示的就是不同的网站,Cookie就会相互隔离。

eTLD信息在Public Suffix List列表中定义,可以通过publicsuffix.org/list查询域名是否为有效顶级域名。
schemeful same-site
关于"same-site的定义一直在不断演变,由此出现将URL Scheme看作是site的一部分的这种策略。基于这种策略可以避免网站遭受基于HTTP协议的一些攻击。
在schemeful same-site规则下,由于scheme不同,http://www.example.com 和https://www.example.com 被认为是不同的站点。
如何判断
Chrome浏览器发送请求时会携带名为Sec-Fetch-Site的Header信息,根据该Header的取值可以判断当前请求是否同源、是否跨站(schemeful-same-site未被记录在Sec-Fetch-Site中)。

Sec-Fetch-Site取值如下:
cross-sitesame-sitesame-originnone
iframe页面总是提示需要重新登录怎么办的更多相关文章
- iframe页面二次登录问题
原文链接:iframe页面二次登录问题 生产问题 问题背景 由于历史原因,公司内部系统有一些页面是基于iframe嵌入的其他系统的页面,之前一直运行正常,最近不知什么原因接连出现访问所有iframe页 ...
- easyui 中iframe嵌套页面,提示弹窗遮罩的解决方法,parent.$.messager.alert和parent.$.messager.confirm
项目中用到easyui 布局,用到north,west,center三个区域,且在center中间区域嵌入iframe标签.在主内容区做一些小提示弹窗(例如删除前的弹窗提示确认)时,会遇到遮罩问题,由 ...
- Asp.net MVC访问框架页中嵌套的iframe页面时,如果session或cookie过期,登录验证超时怎样自动跳转到登录页
一般登录验证的过滤器中,使用验证过滤器的Redirect方法,将请求重定向到指定的URL.但是如果我们要访问的页面是一个嵌套在框架页中的iframe页面时,这种重定向只会对iframe页面凑效,也就是 ...
- Exploit Kit——hacker入侵web,某iframe中将加载RIG EK登录页面,最终下载并执行Monero矿工
RIG Exploit Kit使用PROPagate注入技术传播Monero Miner from:https://www.4hou.com/technology/12310.html 导语:Fire ...
- Android:后台给button绑定onClick事件、当返回项目到手机页面时提示是否退出APP
上一篇文章我们学习了android通过findViewById的方式查找控件,本章将了解button控件,及btton如何绑定控件. 通过android的ui设计工具设计一个登录页面: <Rel ...
- layer.open打开iframe页面的调用父页面方法及关闭
//调用父类方法 window.parent.exportData($('#shownum').val(),$('#splitstr').val()); //关闭iframe页面var index = ...
- ASP.NET连接数据库时,提示“用户 'sa' 登录失败原因: 未与信任 SQL Server 连接相关联
用ASP.NET连接数据库时,提示"用户 'sa' 登录失败.原因: 未与信任 SQL Server 连接相关联.".解决方法:首先检查是不是web.config文件内的用户名密码 ...
- jQuery 互相调用iframe页面中js的方法
1,子iframe内调用父类函数方法: window.parent.func(); 2,子Iframe中获取父界面的元素: $("#xx", window.parent.docum ...
- lhgdialog: iframe页面里面的,确定,关闭、取消按钮的操作
lhgdialog: iframe页面里面的,确定,关闭.取消按钮的操作 如果你正在用lhgdialog,用他人iframe,或者 content:'url:http://www.baidu.com/ ...
随机推荐
- ABP VNext框架基础知识介绍(1)--框架基础类继承关系
在我较早的时候,就开始研究和介绍ABP框架,ABP框架相对一些其他的框架,它整合了很多.net core的新技术和相关应用场景,虽然最早开始ABP框架是基于.net framework,后来也全部转向 ...
- GaussDB(DWS)中共享消息队列实现的三大功能
摘要:本文将详细介绍GaussDB(DWS)中共享消息队列的实现. 本文分享自华为云社区<GaussDB(DWS)CBB组件之共享消息队列介绍>,作者:疯狂朔朔. 1)共享消息队列是什么? ...
- LuoguP7222 [RC-04] 信息学竞赛 题解
Content 给定一个角 \(\alpha\),求 \(\beta=90^\circ-\alpha\). 数据范围:\(\alpha\in[-2^{31},2^{31}-1]\). Solution ...
- mysql 禁止自动提交设置
mysql禁止自动提交的设置, 在my.ini文件里加上如下的一句便可 init_connect='SET autocommit=0' 但是有个问题,对root用户进行autocommit变量的查询, ...
- GAN 简介
GAN 原理: GAN 的主要灵感来源于博弈论中零和博弈的思想,应用到深度学习神经网络上来说,就是通过生成网络 G(Generator)和判别网络 D(Discriminator)不断博弈,进而使 ...
- JAVA整合Redis使用redisTemplate清除库中的所有键值对数据
JAVA整合Redis使用redisTemplate清除库中的所有键值对数据,清除所有缓存数据 Set<String> keys = redisTemplate.keys("*& ...
- vue-组件化编程
1.传统编写方式和组件编写方式的区别 组件方式编写可以很方便的复用和封装某些功能模块/组件的命名最好语义化,方便维护和阅读 编写时,我们可以将某些共用的功能或者样式部分抽象,得到对应的组件,按需要引入 ...
- 【LeetCode】442. Find All Duplicates in an Array 解题报告(Python& C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 字典 原地变负 日期 题目地址:https://le ...
- 从头造轮子:python3 asyncio 之 run(2)
前言 书接上文,本文造第二个轮子,也是asyncio包里面非常常用的一个函数run 一.知识准备 ● 相对于run_until_complete,改动并不大,就是将入口函数重新封装了一下,基础知识主要 ...
- Elasticsearch核心技术(五):搜索API和搜索运行机制
本文将从数据存储和搜索的角度简单分析Elasticsearch的搜索运行机制,主要涉及搜索API.搜索机制.存在问题和解决方案. 4.1 Search API Search API允许用户执行一个搜索 ...