热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

在Rails应用程序中测试签名和加密的Cookie

最近,我一直在对我维护的gem进行测试重构,我需要测试它是否在正确的时间设置了正确的cookie。但是,gem中使用的cookie是已签名

最近,我一直在对我维护的gem进行测试重构,我需要测试它是否在正确的时间设置了正确的COOKIE。 但是,gem中使用的COOKIE是已签名的COOKIE,这对我造成了轻微的打ic。 我以前从未测试过签名COOKIE中的值,而且也不是很清楚该怎么做。

所以我想我会分享我发现的内容,以防万一。

Rails上的COOKIE

在Rails应用程序中,可以使用三种COOKIE:
简单会话COOKIE,签名COOKIE和加密COOKIE。 您可以
通过使用控制器中的COOKIEs对象来设置其中任何一个,如下所示:

class COOKIEsController def indexCOOKIEs[ "simple" ] = "Hello, I am easy to read."COOKIEs.signed[ "protected" ] = "Hello, I can be read, but I can't be tampered with."COOKIEs.encrypted[ "private" ] = "Hello, I can't be read or tampered with."end
end

简单的饼干

简单的COOKIE由纯文本组成。 如果您在浏览器中检查了上面称为“简单”的COOKIE,您将看到文本“您好,我很容易阅读”。

简单的COOKIE可以存储真正无关紧要的数据。 最终用户可以阅读和更改它,并且您的应用程序不会受到影响。

签名的COOKIE

签名的COOKIE不会以纯文本形式发送到浏览器。 取而代之的是,它们由有效载荷和签名组成,并用两个破折号--分隔。 在破折号之前,有效载荷是基数为64的编码数据 。 要读取数据,您可以基于64位对其进行解码。 此数据不是秘密,但由于COOKIE的第二部分是签名,因此不能被篡改。

通过获取应用程序的secret_key_base和COOKIE中的数据的HMAC SHA1摘要来创建签名。 如果您尝试读取COOKIE时更改了COOKIE的内容,则签名将不再与内容匹配,并且Rails将返回nil 。 在ActiveSupport::MessageVerifier这全部由ActiveSupport::MessageVerifier处理。 从上面可以看到,您不必担心,可以将COOKIEs.signed对象当作哈希来对待。

签名的COOKIE对于用户可以读取的数据很有用,但是当您再次将其返回到服务器时,需要信任的是相同的。

加密的COOKIE

加密的COOKIE会更进一步,并加密COOKIE中的数据,然后对其进行签名。 这由ActiveSupport::MessageEncryptor处理,这意味着如果没有secret_key_base您将无法读取或写入此COOKIE。 值得庆幸的是,您无需担心加密问题,使用COOKIEs.encrypted对象,您可以将加密的COOKIE设置为常规哈希来设置。

加密的COOKIE对于要与用户一起存储但不希望它们或任何人读取的私有数据很有用。

测试COOKIE

假设我们现在要测试上面看到的控制器。 我们想
确保我们所有的COOKIE均已正确设置。 测试可能看起来
像这样的东西:

class COOKIEsControllerTest test "should set COOKIEs when getting the index" doget root_urlassert_response :successassert_equal "Hello, I am easy to read." , COOKIEs[ "simple" ]assert_equal "Hello, I can be read, but I can't be tampered with." , COOKIEs[ "protected" ]assert_equal "Hello, I can't be read or tampered with." , COOKIEs[ "private" ]end
end

或使用RSpec Rails:

RSpec.describe COOKIEsController, type: :request doit "should set COOKIEs when getting the index" doget root_urlexpect(response).to have_http_status( :success )expect(COOKIEs[ "simple" ]).to eq( "Hello, I am easy to read." )expect(COOKIEs[ "protected" ]).to eq( "Hello, I can be read, but I can't be tampered with." )expect(COOKIEs[ "private" ]).to eq( "Hello, I can't be read or tampered with." )end
end

但这将在测试签名COOKIE时失败,并且也不会通过加密COOKIE。 如果这些COOKIE已签名或加密,则不能直接从罐子中调用这些COOKIE。

您可能认为您应该针对COOKIE的signedencrypted版本进行测试,如下所示:

assert_equal "Hello, I can be read, but I can't be tampered with." , COOKIEs.signed[ "protected" ]assert_equal "Hello, I can't be read or tampered with." , COOKIEs.encrypted[ "private" ]

那也不行。 至少,如果您使用的是当前推荐的测试控制器的方法(在Minitest中使用ActionDispatch::IntegrationTest或在RSpec中type: :request ActionDispatch::IntegrationTest type: :request ,则它不起作用。

如果您使用的是旧样式ActionController::TestCasetype: :controller ActionController::TestCase type: :controller测试,则COOKIEs.signedCOOKIEs.encrypted将起作用。 如果您的应用程序具有较早的样式测试,请继续阅读以防万一您决定重构它们以使其与当前的Rails方式保持一致。

通过上述测试, COOKIEs对象实际上是Rack::Test::COOKIEJar的实例,该实例不了解您的Rails应用程序机密。

那么我们如何测试这些COOKIE?

这是我接触到的宝石的所在。 我需要测试签名COOKIE的结果,但是我有一个Rack::Test::COOKIEJar对象。 好消息是,我们可以重新使用Rails应用程序自己的ActionDispatch::COOKIEs::COOKIEJar来解码已签名的COOKIE和解密已加密的COOKIE。

为此,您ActionDispatch::COOKIEs::COOKIEJar使用测试中的request对象和COOKIE数据的哈希值来实例化ActionDispatch::COOKIEs::COOKIEJar的实例。 然后,您可以在该COOKIE罐上调用signedencrypted

所以现在测试看起来像:

class COOKIEsControllerTest test "should set COOKIEs when getting the index" doget root_urlassert_response :successassert_equal "Hello, I am easy to read." , COOKIEs[ "simple" ]jar = ActionDispatch::COOKIEs::COOKIEJar.build(request, COOKIEs.to_hash)assert_equal "Hello, I can be read, but I can't be tampered with." , jar.signed[ "protected" ]assert_equal "Hello, I can't be read or tampered with." , jar.encrypted[ "private" ]end
end

或规格看起来像:

RSpec.describe COOKIEsController, type: :request doit "gets COOKIEs from the response" doget root_urlexpect(response).to have_http_status( :success )expect(COOKIEs[ "simple" ]).to eq( "Hello, I am easy to read." )jar = ActionDispatch::COOKIEs::COOKIEJar.build(request, COOKIEs.to_hash)expect(jar.signed[ "protected" ]).to eq( "Hello, I can be read, but I can't be tampered with." )expect(jar.encrypted[ "private" ]).to eq( "Hello, I can't be read or tampered with." )end
end

红色,绿色,零食

在本文中,我们看到了如何在Rails中测试签名或加密的COOKIE。 希望您的测试套件运行为绿色,并且现在覆盖您的COOKIE。

我将回到我正在研究的重构中。 现在,这些COOKIE已被删除,还有很多测试可以覆盖。

From: https://hackernoon.com/testing-signed-and-encrypted-COOKIEs-in-rails-application-358z369v



推荐阅读
  • 开发笔记:Java是如何读取和写入浏览器Cookies的
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了Java是如何读取和写入浏览器Cookies的相关的知识,希望对你有一定的参考价值。首先我 ... [详细]
  • 在Kubernetes上部署JupyterHub的步骤和实验依赖
    本文介绍了在Kubernetes上部署JupyterHub的步骤和实验所需的依赖,包括安装Docker和K8s,使用kubeadm进行安装,以及更新下载的镜像等。 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • Python SQLAlchemy库的使用方法详解
    本文详细介绍了Python中使用SQLAlchemy库的方法。首先对SQLAlchemy进行了简介,包括其定义、适用的数据库类型等。然后讨论了SQLAlchemy提供的两种主要使用模式,即SQL表达式语言和ORM。针对不同的需求,给出了选择哪种模式的建议。最后,介绍了连接数据库的方法,包括创建SQLAlchemy引擎和执行SQL语句的接口。 ... [详细]
  • 如何提高PHP编程技能及推荐高级教程
    本文介绍了如何提高PHP编程技能的方法,推荐了一些高级教程。学习任何一种编程语言都需要长期的坚持和不懈的努力,本文提醒读者要有足够的耐心和时间投入。通过实践操作学习,可以更好地理解和掌握PHP语言的特异性,特别是单引号和双引号的用法。同时,本文也指出了只走马观花看整体而不深入学习的学习方式无法真正掌握这门语言,建议读者要从整体来考虑局部,培养大局观。最后,本文提醒读者完成一个像模像样的网站需要付出更多的努力和实践。 ... [详细]
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • 在Docker中,将主机目录挂载到容器中作为volume使用时,常常会遇到文件权限问题。这是因为容器内外的UID不同所导致的。本文介绍了解决这个问题的方法,包括使用gosu和suexec工具以及在Dockerfile中配置volume的权限。通过这些方法,可以避免在使用Docker时出现无写权限的情况。 ... [详细]
  • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
    本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • imx6ull开发板驱动MT7601U无线网卡的方法和步骤详解
    本文详细介绍了在imx6ull开发板上驱动MT7601U无线网卡的方法和步骤。首先介绍了开发环境和硬件平台,然后说明了MT7601U驱动已经集成在linux内核的linux-4.x.x/drivers/net/wireless/mediatek/mt7601u文件中。接着介绍了移植mt7601u驱动的过程,包括编译内核和配置设备驱动。最后,列举了关键词和相关信息供读者参考。 ... [详细]
  • GreenDAO快速入门
    前言之前在自己做项目的时候,用到了GreenDAO数据库,其实对于数据库辅助工具库从OrmLite,到litePal再到GreenDAO,总是在不停的切换,但是没有真正去了解他们的 ... [详细]
  • Android实战——jsoup实现网络爬虫,糗事百科项目的起步
    本文介绍了Android实战中使用jsoup实现网络爬虫的方法,以糗事百科项目为例。对于初学者来说,数据源的缺乏是做项目的最大烦恼之一。本文讲述了如何使用网络爬虫获取数据,并以糗事百科作为练手项目。同时,提到了使用jsoup需要结合前端基础知识,以及如果学过JS的话可以更轻松地使用该框架。 ... [详细]
  • 超级简单加解密工具的方案和功能
    本文介绍了一个超级简单的加解密工具的方案和功能。该工具可以读取文件头,并根据特定长度进行加密,加密后将加密部分写入源文件。同时,该工具也支持解密操作。加密和解密过程是可逆的。本文还提到了一些相关的功能和使用方法,并给出了Python代码示例。 ... [详细]
  • .NetCoreWebApi生成Swagger接口文档的使用方法
    本文介绍了使用.NetCoreWebApi生成Swagger接口文档的方法,并详细说明了Swagger的定义和功能。通过使用Swagger,可以实现接口和服务的可视化,方便测试人员进行接口测试。同时,还提供了Github链接和具体的步骤,包括创建WebApi工程、引入swagger的包、配置XML文档文件和跨域处理。通过本文,读者可以了解到如何使用Swagger生成接口文档,并加深对Swagger的理解。 ... [详细]
author-avatar
suny
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有