前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Web应用的会话、认证与安全

Web应用的会话、认证与安全

作者头像
搬砖俱乐部
发布2019-06-15 17:36:29
1.4K0
发布2019-06-15 17:36:29
举报
文章被收录于专栏:BanzClubBanzClub

HTTP协议最初是匿名的、无状态的,一次请求和响应一旦结束,客户端和服务端的连接就会关闭,服务器没有信息可以用来判断哪个用户发送的请求,也无法跟踪用户会话。

现代的Web应用都希望可以对客户端的用户行为有一些跟踪和个性化的推荐,也能够对用户信息进行管理,以使站点的用户有更高的体验。早期设计者们有几种技巧可以使站点识别用户,Cookie机制是最好的方式,现在大部分情况下,这些技巧会和Cookie机制配合着使用。

User-Agent是请求时,请求头将用户所用的浏览器信息告知服务器;

Referer是请求头将用户来源页面的URL告知服务器;

用户登录方式来确定用户身份,每次请求时将用户信息通过请求头中的Authorization提供给服务器;

胖URL通过在URL中增加一些用户唯一标识串,在首次访问服务器时,服务器生成一个唯一ID返回给客户端,客户端用服务器可以识别的方式将ID通过URL方式发送给服务器,服务器根据ID可以查找出与其关联的用户会话状态。

Cookie机制基本思想就是让浏览器记录一组服务器特有的信息,每次访问服务器时将这些信息提供给服务器。Cookie是由服务端生成,返回给客户端,并由客户端存储在本地,后面的请求时,将Cookie信息携带传递给服务端,服务端进行检查Cookie状态,工作流程如下:

从Cookie的过期时间上划分,可以分为会话Cookie和持久Cookie,会话Cookie存储在内存中,当关闭浏览器时,Cookie就会消失。持久Cookie存储在硬盘中,不会随着浏览器的关闭而消失,一般手动清理或者到了过期时间,Cookie才会失效。

Cookie属性

  • name:value Cookie通过key:value键值对形式,设置cookie值;
  • domain:cookie设置的域信息;
  • path:所属相对根路径;
  • expires:cookie过期时间,超过过期时间,cookie将会删除;
  • httponly:只能由服务器创建,客户端通过js脚本将无法读取到cookie信息,从而避免cookie内容的泄漏,减少了XSS攻击的;
  • secure:安全cookie是在https访问下的cookie形态,以确保cookie在从客户端传递到服务端过程中始终为加密形式的;

会话

了解完Cookie机制,我们来说一下会话:会话是指客户端与服务端一系列交互过程,这一系列的交互过程可能包含很多次请求和响应,已经说过HTTP协议是无状态的,服务器为了识别哪次请求是同一个客户端的请求,引入了会话机制。通常使用Cookie与Session来实现Web应用的会话管理,Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。

cookie与session实现会话管理的步骤如下:

1、客户端首次访问服务器,服务器创建会话,产生session对象,用于记录用户信息;

2、session对象分配一个唯一标识sessionid信息,通过设置set-cookie到响应头中,以cookie形式返回给客户端;

3、客户端将拿到的cookie中的sessionid信息保存起来,当客户端再次访问服务端时,将cookie信息设置到请求头中,发送给服务器。

4、服务器得到sessionid后,从服务器中查询出来会话信息,得到session对象,从而跟踪客户端的状态。

Cookie和Session都有过期时间,超过过期时间或者关闭浏览器都会使会话信息丢失。还有一些浏览器是禁止Cookie的,这时候可以使用胖URL方式继续携带sessionid信息与服务端交互。

认证

很多Web应用和页面需要有特定身份的人,才可以访问,为了达到这个目的,需要使用服务的客户端进行身份的确认,这就是认证。HTTP协议标准提供了基本认证和摘要认证,不过都不怎么常用,下面结合工作中的一些场景,说一下目前比较常用的认证方式。

用户名、密码认证,通常网站都会通过表单提交的方式,提交用户名/密码,来确认网站使用者的用户身份。同时,结合着Cookie和Session的方式,完成服务端和客户端基于用户行为的交互,对一些特定资源进行访问、管理。另外,这种认证过程没有标准化,每个网站都有自己的一套逻辑来实现。

SSL客户端认证,因为用户名/密码方式,会存在用户名/密码被盗用的情况,有可能被第三者冒充。SSL客户端认证需要客户端安装数字证书,并且仍然需要表单提交用户信息,双重保障确认客户端的身份。

OpenApi授权认证,除了Web应用的认证,还有基于Web接口服务的认证,这些服务通常都是开放的,需要客户端使用预先定义好的认证规则,才能使用接口服务,比较常用的Token认证方式。

token认证通常是通过一系列的加密算法,可以对报文加密,签名,并生成一个token,发送给服务端,服务端通过验签、解密等,从而得到正确的报文和真实的客户端身份。当然,这种方式的加密算法可以有很多,MD5加密、对称加密、非对称加密都可以,就看服务提供者怎么约定规则。

JWT认证是目前比较常用的Token认证规范,JWT(JSON Web Tokens) 通常由三部分组成头部、载荷与签名,头部主要是Token类型和使用的算法;载荷是Token的具体内容,包括发行方、发行时间、过期时间等;签名包括加密之后的头部和载荷,还有用于加密密钥部分。使用时将三个部分组合到一起就得到了完整的JWT,可以通过URL形式,或者通过请求头中 Authorization传递给服务端。

每种认证方式都有自己的使用场景我们知道服务端通常使用Session方式管理应用的会话信息,这种模式的问题在于扩展性不好,单机没有问题,如果是服务器集群,或者跨域的服务导向架构,就需要session数据共享,对session信息做持久化处理,这种方案工程量比较大,而且,session服务出现问题将影响整个应用。

JWT提供了另外一种方式,它不再需要服务端维护会话信息了,所有数据都存储在客户端,每次请求时将JWT发送给服务器,服务器只需验证令牌是否过期、是否合法就可以确定用户身份。不过,建议JWT配合HTTPS一起使用,保证传输过程的安全性,避免信息的盗用。

安全

HTTP协议本身不具有加密的功能,无法对请求和响应的报文进行加密。所以,当请求和响应报文在计算机网络里传播的时候,有可能被其他人恶意的窥测到(抓包工具),就可以拿到报文中的内容。而通过和SSL(Secure Socket Layer 安全套接层)或TSL(Transport Layer Security 安全层传输协议)的组合使用,可以实现加密HTTP的通信内容。用SSL(TSL)建立安全通信线路的HTTP通信,就叫HTTPS(HTTP Secure 超文本传输安全协议)。

在HTTP协议中,通信双方不会对请求和响应方的身份进行确认,这就使HTTP通信存在一些安全隐患。无法确定服务器的身份,有可能不是客户端真实想请求的服务端,是已伪装的Web服务器;无法确定客户端是否是真正需要接收响应的客户端,可能是伪装的客户端;无法确定通信对方是否有某些特定资源的权限;无法避免DoS攻击(Denial of Service 拒绝服务攻击 恶意访问服务器,使其不能提供正常的服务)。而使用HTTPS不仅可以建立安全的通信线路进行加密传输,还可以使用被称为证书的手段,来确认服务器和客户端的身份。

HTTP协议无法证明通信报文的完整性,也就是通信双方,无法确认对方发送过来的信息是否是前后相同的,有可能在传输过程中,被攻击者拦截并且篡改了。这种攻击手段叫中间人攻击(MITM Man-in-the-Middle attack)。其实,我们可以通过客户端程序,自己实现校验信息的完整性,但协议本身不支持确认机制。而使用HTTPS可以保证传递信息的完整性。

HTTPS不是应用层新的协议,只是HTTP通信接口部分用SSL和TSL协议代替而已。SSL是独立与HTTP的协议,不光HTTP协议,其他运行在应用层的协议都可以配合SSL协议使用。

SSL采用公开秘钥的加密方式实现,使用一对非对称密钥,一把叫公开密钥(public key),一把叫做私有密钥(provate key)。发送报文方,通过使用接收方的公钥进行加密处理,接收方收到报文后,使用自己的密钥进行解密,这样避免了报文的明文传播,也避免被攻击者盗走。这种非对称加密算法还可以解决信息完整性和身份认证的问题。报文发送方,通过使用自己的私钥加密(这个过程就叫数字签名),报文接收方使用发送方的公钥可以校验报文是否被篡改,也可以确认报文是否为确定方发送的。

通信安全首先应该确认双方的身份,服务提供方通过向具有公信力的第三方数字认证机构(CA Certificate Authority)申请获得公钥证书并据此与客户端进行交互。证书的申请和交互步骤如下:

1、HTTPS服务器方向数字证书认证机构CA提出公开密钥的申请;

2、CA对申请者提供的信息进行审核,审核通过后,CA会用自己的私钥对已申请的公开密钥做数字签名,将该公开密钥与公钥证书进行绑定,然后分配这个证书给申请者;

3、每当有客户端发起HTTPS请求时,服务器会将公钥证书发送给客户端,以进行公开密钥加密方式通信;

4、接到证书的客户端使用CA的公开密钥,对那张证书上的数字签名进行验证,一旦验证通过,客户端便可明确两件事:

一、认证服务器公开密钥的是真实有效的CA。

二、服务器的公开密钥是值得信赖的。

CA 的公开密钥必须安全地转交给客户端。在传输过程中要做到这点很难,因此多数浏览器会事先植入常用CA的公开密钥。

5、双方开始通信经过以上过程,便可以确信服务器端的身份。此外,也有用以证明客户端身份的客户端证书,但一般只使用在对安全性要求很高和需要确定客户端身份的应用比如网银系统(U-key)中。

服务双方有了公钥证书就可以进行HTTPS安全交互,HTTPS通信过程如下:

1、客户端发起报文,准备开始SSL通信,报文中包括客户端支持的SSL版本,加密组件列表(加密算法及密钥长度);

2、服务端确认了客户端的加密信息,会响应服务器的加密组件,这些加密组件是通过接收客户端加密组件中筛选处理的;

3、服务器端会发送Ceriificate报文,报文中包含公开密钥证书;

4、服务器端还会返回第一阶段服务器响应结束的报文,这时,第一次SSL握手结束;

5、客户端以Client Key Exchange报文作为回应,报文中包含通信加密中使用的一种被称为Pre-master secret的随机密码串;

6、接着客户端继续发送Change Cipher Spec报文,该报文会提示服务器,在此报文之后的通信会采用Pre-master secret密钥加密;

7、客户端发送Finished报文,该报文包括连接至今全部报文的整体校验值,如果服务端能够完整的解密这个报文,第二次SSL握手结束;

8、服务器同样发送Change Cipher Spec报文;

9、服务器同样发送Finished报文;

10、服务器和客户端的Finish的报文交换完毕后,SSL连接就建立完成了,从此处开始,就可以进行HTTP报文的请求和响应了;

11、断开连接,终止通信。

SSL技术最初是由网景公司开发的,后转由IETF负责并改称为TSL,目前常用的是SSL3.0和TSL2.0版本,通常通称为SSL协议。2016年6月,苹果公司宣布从2017 年1月1日起APP Store中的IOS应用必须启用App Transport Security(ATS)安全功能,这就要求之后所有上架的IOS应用与服务器通信必须使用TLS版本1.2及以上的HTTPS。在此之前,国外很多网站包 括google,facebook等都已支持全站HTTPS。国内的各大网站百度,阿里巴巴,京东等电商网站在也先后实现全站HTTPS,国内各大银行虽然没有全部启用全站HTTPS,但也至少在登陆或付款页面启用HTTPS,可以说,启用HTTPS已经成了很多大型网站的选择。

HTTPS协议也有自身的缺点,相比于HTTP协议,HTTPS通信双方需要进行加解密从而会使通信时延增加,而且SSL通信会消耗硬件资源,会使性能整体不如HTTP协议;HTTPS需要购买证书,而且启用HTTPS也会面临着应用升级的成本增加,这也是一个制约因素。不过,随着HTTPS和HTTP/2.0技术的发展,应用HTTPS的成本会越来越低,带来的效果也会越来越明显,启用HTTPS是大势所趋。


1、《HTTP权威指南》

2、《计算机网络 第七版》

3、《图解HTTP》

4、https://www.cnblogs.com/teeva/p/4474602.html

5、http://www.cnblogs.com/anny0404/p/5318692.html

6、http://fanqieto.top/2017/09/23/%E5%85%A8%E9%9D%A2%E8%A7%A3%E8%AF%BBhttp/

7、https://www.cnblogs.com/ludashi/p/6237715.html

8、《浅析HTTPS 发展现状和趋势》 高度

9、http://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-02-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 BanzClub 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
SSL 证书
腾讯云 SSL 证书(SSL Certificates)为您提供 SSL 证书的申请、管理、部署等服务,为您提供一站式 HTTPS 解决方案。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档