登录授权、TCP/IP、HTTPS

今天继续纯理论的东东,比较枯燥,但是又很重要,坚持。。
登录和授权
登录和授权的区别:
  • 登录:身份认证,即确认「你是你」的过程。
  • 授权:由身份或持有的令牌确认享有某些权限(例如获取用户信息)。登录过程实质上的目的也是为了确认权限。
HTTP 中确认授权(或登录)的两种方式:
  1. 通过 Cookie
  2. 通过 Authorization Header

Cookie[如今用得少]

  • 起源:「购物车」功能的需求,由 Netscape 浏览器开发团队打造。
  • 工作机制:

    1、服务器需要客户端保存的内容,放在 Set-Cookie headers 里返回,客户端会自动保存。

    2、客户端保存的 Cookies,会在之后的所有请求里都携带进 Cookie header ⾥发回给服务器。

    3、客户端保存 Cookie 是按照服务器域名来分类的,例如 shop.com 发回的 Cookie 保存下来以后,在之后向 games.com 的请求中并不会携带。

    4、客户端保存的 Cookie 在超时后会被删除、没有设置超时时间的 Cookie (称作 Session Cookie)在浏览器关闭后就会⾃动删除;另外,服务器也可以主动删除还未过期的客户端 Cookies。


    具体如下:

        比如说客户端要在Cookie里面保存一个苹果信息,先发起这个苹果的请求,如下:
        

        此时服务器收到请求之后就会给客户端一个response,然后携带一个Set-Cookie的头信息,如下:
        
        此时客户端就会将其存到Cookie当中,如下:
        

        
        此时这个存Cookie的动态做为开发者是不需要关心的,用户想再添加一个香焦到购物车时,则请求时浏览器自动会将客户端本地已经存的cookie信息带到请求头里面,如下:
        
        此时服务器收到之后,在response的cookie头中就会携带两个水果信息了,如下:
        

        然后客户端看到之后则更新cookie,如下:
        

       接着客户端想要把购买车当中的商品进行结账,则在请求时会将存在cookie中的所有信息一并自动发往服务器,如下:
       

  • Cookie的作用:
    1、会话管理:登录状态、购物车。
         这里以Cookie管理登录状态为例说明一下:
         
         此时用户已经登录了,服务器就会记录其登录状态,如下:
        

        此时在reponse头中会将此sessionid放到cookie头返给客户端,如下:
        

        此时客户端就会将此cookie记录下来:

        

        此时如果客户端再次请求时则会自动将cookie带到头信息中,如下:
        
        此时服务器发现该用户已经登录了,则直接返回用户的信息给客户端,如下:
        
        如果说此时用户还想去添加购物车,则会多一个cookie信息,比如用户往购买端添加了一个苹果,如下:
        

        此时服务器在resonpse中的cookie头中就会有新的信息,如下:
        

        此时客户端自动记录新的cookie,如下:
        

    2、个性化:⽤户偏好、主题。
        这里以用户偏好为例:用户请求:
        

        此时response中返回用户的一个信息:
        

        然后存于客户端的cookie中:

        

        此时用户想访问蓝色主题了,请求信息会是如下,当然之前的cookie会自动带上去:

        

        然后服务端直接返回ok,并给用户展示蓝色的主题,如下:
        

        之后用户如果再访问其它页面,服务器就知道用户也希望是访问蓝色主题了,如下:
        

    3、Tracking:分析用户⾏为。
        这个国外用得比较多,通常在网站上会有一个类似的提示:“你正在访问的网站正在使用cookie进行网站的行踪,这个对你来说是没有害处的,而且我们一定不会将其公开,只是自己使用的,请理解”,因为有些国外法律是不允许的,必须声明一下,那具体怎么来跟踪呢,下面来大致了解一下:

        客户端请求:
        

        然后此时服务器返回的信息就有点意思了:
        

        此时客户端会记录cookie信息:
        

        接着开启请求图片了,也就是第三方的服务器,如下:
        

        接着该请求的response中也会有cookie信息下发:
        

        然后记录于客户端中:
        

        如果用户再访问了其它的网站,则就可以分析其用户上网的形为,便于投放商业广告挣钱之类的。 

  • HttpOnly 和 Secure 属性(了解即可)
    HttpOnly:这个 Cookie 只能⽤于 HTTP 请求,不能被 JavaScript 调用。它可以防⽌本地代码滥用Cookie。
    Secure:这个 Cookie 在⽤于请求时,只能用于安全请求(HTTPS),不能⽤于普通的 HTTP 请求。
  • XSS (Cross-site scripting)(了解即可):跨站脚本攻击。即使用 JavaScript 拿到浏览器的 Cookie 之后,发送到自⼰的⽹站,以这种⽅式来盗取⽤户 Cookie。应对⽅方式:Server 在发送 Cookie 时,敏感的 Cookie 加上 HttpOnly。
  • XSRF (Cross-site request forgery)(了解即可):跨站请求伪造。即在⽤户不知情的情况下访问 已经保存了 Cookie 的⽹站,以此来越权操作⽤户账户(例如盗取用户资⾦)。应对⽅式主要是 从服务器安全⻆度考虑,就不多说了。主要是加Referer头信息,如:Referer:www.baidu.com

Authorization[如今比较流行]

两种主流方式: Basic 和 Bearer

Basic:

格式:Authorization: Basic <username:password(Base64ed)>
例如:⽤户名是 rengwuxian ,密码是 123456 ,那么连起来就是 rengwuxian:123456 ;把这个字符串进⾏ Base64 编码后,结果是 cmVuZ3d1eGlhbjoxMjM0NTY= 。那么,最终的 Authorization header 的内容就是: 

Authorization: Basic cmVuZ3d1eGlhbjoxMjM0NTY=

Bearer【如今项目中采用的就是它】:

Bearer表示持票人,也就是持有了尚方宝剑那不就有权限了。

  • 格式:Authorization: Bearer <bearer token> 
  • bearer token 的获取⽅式:通过 OAuth2 的授权流程
  • OAuth2 的流程【重点】:

    先来直观看一下OAuth2的授权流程,这里以掘金网(https://juejin.im/)用github的账号来登录来例,首先查看一下github账号里面有没有对掘金网进行授权,如下:

    然后打开掘金网点登录:

    然后此时咱们点击授权就可以正常的登录掘金了,如下:

    其上面的流程可以描述为如下步骤:

    1、第三方⽹站向授权方⽹站申请第三方授权合作,拿到 client id 和 client secret。

    2、⽤户在使用第三⽅⽹站时,点击「通过 XX (如 GitHub) 授权」按钮,第三方⽹站将⻚⾯跳

    转到授权⽅⽹站,并传入 client id 作为⾃⼰的身份标识。
    3、授权方⽹站根据 client id ,将第三⽅⽹站的信息和第三方⽹站需要的⽤户权限展示给⽤户,并询问用户是否同意授权。

    4、⽤户点击「同意授权」按钮后,授权方⽹站将⻚⾯跳转回第三⽅⽹站,并传入Authorization code 作为⽤户认可的凭证。

    5、第三⽅⽹站将 Authorization code 发送回⾃⼰的服务器。

    6、服务器将 Authorization code 和⾃⼰的 client secret一并发送给授权⽅的服务器,授权方服务器在验证通过后,返回 access token。OAuth 流程结束。




    7、在上面的过程结束之后,第三方⽹站的服务器(或者有时客户端也会)就可以使用 access token 作为用户授权的令牌,向授权方⽹站发送请求来获取⽤户信息或操作用户账户。

  • FAQ:为什么 OAuth 要引入 Authorization code,并需要申请授权的第三⽅将 Authorization code 发送回⾃⼰的服务器,再从服务器来获取 access token,⽽不是直接返回 access token ?这样复杂的流程意义何在? 为了安全。OAuth 不强制授权流程必须使用 HTTPS,因此需要保证当通信路径中存在窃听者时,依然具有⾜够⾼的安全性。 
  • 第三⽅App通过微信登录的流程,也是一个 OAuth2 流程【自已的项目中也信成了微信的登录】:
    在正式说三方登录的流程之前先得说个东东,由于三方登录比三方授权要来得晚一些,所以这里的第三方指的是微信,而非我们的网站,而上面说的三方授权的第三方的角度是不一样的,例如上面说的场景:

    三方是指的我们开发的网站,所以这个需要知道其概念,比较绕。下面来说一下微信的整个过程:

    1、第三方 App 向腾讯申请第三方授权合作,拿到 client id 和 client secret。

    2、用户在使用第三方 App 时,点击「通过微信登录」,第三方 App 将使用微信 SDK 跳转到微信,并传⼊⾃⼰的 client id 作为⾃⼰的身份标识。
    3、微信通过和服务器交互,拿到第三方 App 的信息,并显示在界⾯中,然后询问⽤用户是否同意授权该 App 使用微信来登录。
    4、⽤户点击「使用微信登录」后,微信和服务器交互将授权信息提交,然后跳转回第三方App,并传⼊ Authorization code 作为用户认可的凭证。
    5、第三方 App 调用⾃⼰服务器的「微信登录」Api,并传入 Authorization code,然后等待服务器的响应。
    6、服务器在收到登录请求后,拿收到的 Authorization code 去向微信的第三方授权接口发送请求,将 Authorization code 和⾃⼰的 client secret ⼀起作为参数发送,微信在验证通过后,返回 access token。
    7、服务器在收到 access token 后,⽴即拿着 access token 去向微信的用户信息接⼝发送请求,微信验证通过后,返回用户信息。
    8、服务器在收到⽤户信息后,在⾃⼰的数据库中为⽤户创建⼀个账户,并使用从微信服务器拿来的⽤户信息填入⾃⼰的数据库,以及将⽤户的 ID 和⽤户的微信 ID 做关联。
    9、用户创建完成后,服务器向客户端的请求发送响应,传送回刚创建好的⽤户信息。
    10、客户端收到服务器响应,⽤户登录成功。
  • 在⾃家App中使用Bearer token
    有的 App 会在 Api 的设计中,将登录和授权设计成类似 OAuth2 的过程,但简化掉 Authorization code 概念。即:登录接口请求成功时,会返回 access token,然后客户端在之后的请求中,就可以使用这个 access token 来当做 bearer token 进行⽤户操作了。
  • Refresh token
    大概服务器返回的是如下格式:
    ⽤法:access token 有失效时间,在它失效后,调用 refresh token 接口,传入 refresh_token 来获取新的 access token。 

    ⽬的:安全。当 access token 失窃,由于它有失效时间,因此坏⼈只有较短的时间来「做坏 事」;同时,由于(在标准的 OAuth2 流程中)refresh token 永远只存在与第三方服务的服务 器中,因此 refresh token ⼏乎没有失窃的⻛险。

TCP/IP

概念
一系列协议所组成的一个⽹络分层模型。
 
为什么要分层?

这个理解了之后对于分层模型就能达到一个比较好的认识,下面来阐述一下:

按照一个完美理想化的模型,只需要HTTP来进行传送,如下:

那。。还要啥分层呢?因为网络是不稳性的, 而且网络中的数据可能会很大,如果中途传失败了则还得重头开始将此数据传一遍,那网络的利用率是极低的,比如说要传这个数据,代表是个非常非常大的数据:

要想改善,则可以将数据进行分段进行传输,所以可以将大数据拆成几段,如下:

比如说1、2、4传输成功了,但是!!3失败了,那只要重新传第3块数据既可,如果不分块那等于得重传整个数据,效率大大降低,由于有分块的出现,而且上层协议除了HTTP之外,还有SMTP、FTP等,它们也都有同样的需求需要将数据进行拆分处理,那么此时分层也应运而生了,单独抽出来一层只处理包的分发,这一层也就是:

关于数据拆分及重试等就专门由这一层来处理了,上层不用管这些细节了。

好,还得继续要细分一下层,我们知道TCP是可靠的传输,如果传输失败了则会重新传,而对应的不可靠传输则为UDP,比如我们玩游戏如果因为网络原因卡住了,待网络正常之后,卡掉的那部分是不需要重新再传一遍的,而TCP、UDP都有网络寻址的功能,所以又得抽出来一层单独来进行数据传输,如下:

这一层是不会管数据有没有传成功了。最后网络模型分层还有最后一层,数据链路层,为网络提供实质的支持,如以太岗、WIFI,比较好理解:

而网络不是说有七层模型么,如网上所说:

 

,其实这是说的是TCP/IP的四层协议模型,总结一下:

TCP 连接

什么叫做连接
通信双方建立确认「可以通信」,不会将对方的消息丢弃,即为「建立连接」
TCP 连接的建立与关闭

长连接

为什么要⻓连接?
因为移动⽹络并不在 Internet 中,⽽是在运营商的内网,并不具有真正的公网 IP,因此当某个 TCP 连接在一段时间不通信之后,⽹关会出于⽹络性能考虑⽽关闭这条 TCP 连接和公⽹的连接通道,导致这个TCP端⼝不再能收到外部通信消息,即 TCP 连接被动关闭。
⻓连的实现方式
心跳。即在一定间隔时间内,使用 TCP 连接发送超短无意义消息来让⽹关不能将⾃⼰定义为「空闲连接」,从而防止⽹关将⾃⼰的连接关闭。

HTTPS【重点】

定义:

HTTP over SSL 的简称,即工作在 SSL(Secure Socket Layer) (或 TLS(Transport Layer Secure))上的 HTTP。说白了就是加密通信的 HTTP。它不是一个单独的协议,而是在HTTP之下增加的一个安全层,用于保障HTTP的加密传输。

工作原理: 

在客户端和服务器之间协商出一套对称密钥,每次发送信息之前将内容加密,收到之后解密,达到内容的加密传输。

为什么不直接⽤⾮对称加密?

⾮对称加密由于使用了复杂的数学原理,因此计算相当复杂,如果完全使用⾮对称加密来加密通信内容,会严重影响⽹络通信的性能。

HTTPS连接建立的过程

其总的过程如下:
1、客户端请求建立TLS连接。
2、服务器发回证书。
3、客户端验证服务器证书。
4、客户端信任服务器后,和服务器协商对称密钥。
5、使用对称密钥开始通信。【只有这一步才是HTTP,之前的都是纯粹的tcp】
其具体的过程如下:
1. Client Hello。
首先客户端给服务器发送消息,说"我要建立连接"。然后还会向服务器附加如下信息:
a、我可以按受的SSL/TLS的版本,比如我支持TLS1.0、TLS1.1,也支持SSL3.0,都会一起发给服务端。
b、Cipher Suite(加密套件):对称加密算法、非对称加密算法、hash算法。其中hash不是在上一节中说是不属于加密算法的嘛,其实它是参与加密算法的验证的。可能会加好多条Cipher Suite,多种组合,如下:
c、随机数:是为了将来计算加密密钥用的,暂时木有用。
d、Server name:
2. Server Hello。
服务端此时会给客户端发一个消息,说“好的,你建立吧!”。
然后还会附加一下其它的信息:

3. 服务器证书信任建⽴。
服务器将证书发回给客户端,其核心是服务器非对称加密的公钥,如下:

接着客户端拿到了服务器的这个公钥信息则就可以做一些事情了,但是!!客户端是需要对该证书进行验证的,毕境之前步骤都是TCP明文的,有可能服务器下发的这个证书信息会被篡改,所以证书里面还有服务器地址、证书签名,如下:

那,校验的核心问题就回到了怎么来验证这个"证书签名"了,其实服务器还会发回来一个证书发布方信息,也就"证书机构", 所以又会有如下信息存在:

应该说蓝色的信息确实是被黄色的信息所签发的,这样整个验证就完了么?木有,还有最后一步,因为证书机构也有可能伪造,所以需要能证明这黄色部分也是真实的,这时就还得由该证书机构的签发方的信息来验证了,如下:

我们以掘金的网站的证书信息直观的感受一下:

那么,还有一个问题,我怎么知道最后一层的根证书就是真的而不是伪造的呢?这时因为这一层的验证是可以找到可靠来源的,来自操作系统内部!每一个操作系统都能找到根证书机构的列表,对于MAC根证书的查看在这:

然后可以在列表中搜一下我们想要查看的,还是以掘金的根证书为例,查一下是否在系统根证书列表中:

而根证书是在操作系统在发布时一起打发官方认证了的,所以到了根证书就是无条件信任的,其中对于中间的证书机构这一层其实是可以去掉,而用根证书直接对证书进行签名,如下:

但是如今大多数方案都会有一个中间机构来签,因为根证书机构是很忙的。以上就是整个服务器证书的验证过程。

此时客户端就拿到了服务器证书的公钥了,如下:

然后就会做唯一一次非对称加密的过程,并把非对称加密加密信息发送给服务器。

4. Pre-master Secret。
而此加密信息就是它,它也是一个随机信息,所以它是整个过程的第三个随机数,如下:

接着会将三个随机数用算法得到一个Master Secret了,如下:

接着用这个Master Secret来计算加密密钥啦,具体有如下东东:

那有个问题:为啥加密密钥还分客户端和服务器端,也就是说客户端发消息加密时用客户端加密密钥,而服务端发消息加密时用服务端加密密钥,其原因还是防贼,这样会更安全一点。

另外啥叫Mac Secret呢?这里首先需要了解一下HMAC(Hash-based Message Authenticate Code),其实它是一个改良版本Hash,举个例子:

我们通常的MD5结果可能如下列等式:

MD5(a) = b;

而HMAC呢它的等式可能会是这样:

HMAC(a) = MD5(fun(a))  = C

也就是说其实就是对MD5做了一些处理让其更加难以破解,仅此而已。

其中这个Mac Secret是用来进行身份验证的,而客户端加密密钥和服务端加密密钥是用来进行加密用的。至此客户端就足够能发加密消息了,非常安全了,此时就还需要进行倒数第二步用来进行验证看客户端和服务端的加密算法能不能用,如下。

5. 客户端通知:将使用加密通信。
注意:不是说就这几个字,而是有几个字节。
6. 客户端发送:Finished。
注意:这里发送的是一大堆内容而非一个字节,具体的内容会是:

其中会对打包的数据进行一下HMAC,服务器收到之后则会对签名进行验证,如果能正常识别出客户端的信息,那证明客户端发的消息是非常之信任可靠的了。

7. 服务器通知:将使用加密通信。
上面是客户端发了之后,服务器也开始要发了。
8. 服务器发送:Finished。
此时这个消息会包含更多的消息,如下:

然后客户端如果能正常识别出来,那双方的最后验证就已经完了,接下来客户端就可以正式跟服务器发送一个HTTPS的请求了,也是第一个HTTPS的请求,具体请求消息大概会是如下:

此时消息内容被客户端加密密钥给加密了,除了前几个字是明文的,只知道是应用层的消息了,如下:

同理,服务器收到之后是能看懂客户端发的是啥,回消息的格式也差不多,用了服务端加密密钥进行了加密了。

以上是HTTPS连接建立的完整过程,好复杂,不过理解这块的人也不多,所以再复杂也得理解喽。

在Android中使用HTTPS

正常情况:
直接使用
什么时候会不⾏?
  • ⽤的是⾃签名证书(例如只⽤于内⽹的https);
  • 证书信息不全,缺乏中间证书机构(可能性不⼤);
  • 手机操作系统较旧,没有安装最新加入的根证书;
怎么办?
⾃⼰写证书验证过程,如何写呢?google官网其实有类似的介绍,链接如下:https://developer.android.com/training/articles/security-ssl,这个需求比较少,等到时真实遇到此需求之后到时再研究一下既可。

posted on 2019-02-11 16:12  cexo  阅读(1093)  评论(0编辑  收藏  举报

导航