登录与授权、HTTPS、TCP/IP 协议族

登录和授权

登录和授权使用的方式

Cookie是个机制,浏览器只做存。修改是服务器通过set cookie发给浏览器。

  • 由来:购物车

  • 工作机制:
    hencoder/Cookie机制1
    hencoder/Cookie机制2
    ​ 客户端发送购物车信息给服务器,服务器接收到后Set-Cookie(其中cart只是个名字是服务端定的)返回给客户端(服务器不存储)
    ​ 客户端接收到Set-Cookie存储Cookie。
    ​ 客户端再次发送新消息时把Cookie信息带过去,服务器接收到后Set-Cookie全部返回给客户端,客户端接收到Set-Cookie信息存储Cookie信息。

  • 作用:

    • 会话管理:登录状态、购物车等
      hencoder/Cookie机制3
      hencoder/Cookie机制4
    • 个性化:用户偏好、主题
      hencoder/Cookie机制5
    • Tracking:分析用户行为
      hencoder/Cookie机制6

XSS(Cross-site scripting)(了解即可):HttpOnly

跨站脚本攻击。即使⽤ JavaScript 拿到浏览器的Cookie 之后,发送到⾃⼰的网站,以这种⽅式来盗取⽤户 Cookie。应对⽅式:Server 在发送Cookie 时,敏感的 Cookie 加上 HttpOnly。

  • 应对⽅式:HttpOnly——这个 Cookie 只能⽤于 HTTP 请求,不能被 JavaScript 调⽤。它可以防⽌本地代码滥⽤ Cookie。

    如:Set-Cookie:sessionId=123;HttpOnly

XSRF(Cross-site request forgery)(了解即可):Referer

跨站请求伪造。即在⽤户不知情的情况下访问已经保存了 Cookie 的⽹站,以此来越权操作⽤户账户(例如盗取⽤户资⾦)。应对⽅式主要是从服务器安全⻆度考虑,就不多说了。

  • 应对⽅式:Referer 校验。(历史原因,正确单词是referrer)

    referer记录的是从哪个网站过来的

Authorization

两种主流方式:Basic和Bearer

Basic:

  • 格式:Authorization:Basic <username:password(Base64ed)>
    通过计算得来的
  • 例子:github的token给客户端登录

Bearer:(持票人)

  • 格式:Authorization:Bearer <bearer token>
    让授权方给予
  • bearer token
OAuth2:(第三方验证)
OAuth2流程
1
2
3
get /user http/1.1
Host: github.com
Authorization: Bearer abcccc

例子:掘金网站用第三方github登录方式(github给掘金授权);第三方登录的第三方是github,第三方授权的第三方是掘金;流程:github授权(访问一些关键信息的权限)给掘金,掘金有了权限后再去获取github的头像、昵称等信息(这一过程github并不知道它登录了哪里),掘金拿到信息登录的过程它是第一方。

第三方登录是产品角度的叫法。在技术角度只是授权(Authorize)访问一些头像昵称等信息(那个“第三方”根本不知道它登录了啥)
hencoder/OAuth1

这个client_id是开发这个3rd-party.com的时候向github平台注册的,github平台给这个平台分配的client_id

hencoder/OAuth2

3rd-party.com使用“github第三方登录”方式

hencoder/OAuth3

github返回Authorization Code给登录的网站,这个网站就能根据这个code去获取github上的头像等信息

hencoder/OAuth4

其中的client_secret不能丢,否则坏人就能拿它去做坏事

完整流程:
hencoder/OAuth5
步骤:

  • 开发者先在 github.com 这个第三方平台上进行注册,会得到 client_id 和 client_secret;
  • 在浏览器上访问 github.com 获取授权的时候会把 client_id 带过去;
  • github.com 收到 client_id 会返回一个授权码 Authorization code;
  • 浏览器获取到授权码后提交给后台(为了安全,浏览器不可信任);
  • 后台接收到 Authorization code 后,再把它和 client_secret 一起发送到 github.com 来获取 access_token;这样整个 OAuth2 流程就完成了。

后续向 github.com 请求个人头像等信息只要让服务器带上 access_token 即可(”bearer+值”的形式)

微信登录

是个完整的OAuth2流程

为了安全考虑:
客户端获取到微信授权码Authorization Code后,应该给服务端,服务端去跟微信的服务端通信,获取微信的access token等信息,再提供给客户端。客户端不应该拿token和Secret

自家App中使用Bearer token

App获取到token后,下次请求直接带上给服务端

refresh token

为了安全,token失效了不让客户重新授权,直接告诉第三方github让原来的token失效掉

1
2
post /refresh_token http/1.1
refresh_token=ababab

TCP/IP协议族

由于网络的不稳定,需要网络分层模型
hencoder/TCP-IP协议族

  • Application Layer应用层:HTTP、FTP、DNS
  • Transport Layer传输层:TCP、UDP
    TCP:会把数据分包进行传,失败会重传(数据严谨性)
    UDP:不是所有场景需要重传,比如游戏
  • Internet Layer网络层:IP
    IP层(寻址作用)接收到就往目的传,不关心传成功与否
  • Link Layer数据链路层:以太网、Wi-Fi
    实际传输数据

TCP 连接(是有状态的)

通信双⽅建⽴确认「可以通信」,不会将对⽅的消息丢弃,即为「建⽴连接」

TCP 连接的建⽴与关闭

三次握手(连三下)
hencoder/TCP连接建立

  1. 请求方发送消息给接收方:我要给你发消息了
  2. 接收方发送消息给请求方:好的,我知道了,我也要给你发消息了
  3. 请求方发送消息给接收方:好的,我知道了

四次挥手(连四下)
hencoder/TCP连接关闭

  1. 请求方发送消息给接收方:我不给你发消息了
  2. 接收方发送消息给请求方:好的,我知道了(可能还有消息没发完,所以不告诉请求方进行关闭)
  3. 接收方发送消息给请求方:(他把消息发完了)我不给你发消息了
  4. 请求方发送消息给接收方:好的,我知道了(此时TCP连接关闭)

长连接

为什么要长连接?

因为移动网络并不在 Internet 中,而是在运营商的内网,并不具有真正的公网 IP,因此当某个TCP 在一段时间不通信后网关会考虑网络性能而关闭这条 TCP 连接和公网的连接通道,那么这个 TCP端口不再收到外部通信消息,即 TCP连接被动关闭。

长连接的实现方式

心跳。在一定时间间隔内使用 TCP 发送超短无意义消息来让网关不能把这个连接归为“空闲连接”,从而防止这个连接被关闭。

HTTPS

定义

HTTP over SSL的简称,即工作在SSL(或TLS)上的HTTP。说白了就是加密通信的HTTP。

HTTP是种协议,HTTPS不是个单独的协议。是HTTP建立在SSL上的

SSL:Secure Socket Layer(以前的) -> TLS Transport Layer Secure(现在的)

HTTPS是种概念上的层,是在HTTP传输数据前进行加密再传的东西(更靠近HTTP这一层)

工作原理

本质:在客户端和服务器之间协商出一个对称密钥(用非对称加密商讨),每次发送信息之前将内容加密,收到之后解密,达到内容的加密传输。

不用非对称加密的原因

从数学方面理解,它要经过复杂的计算,效率太慢。

HTTPS 连接建⽴的过程

1
2
3
4
5
1. 客户端请求建立TLS连接
2. 服务器发回证书
3. 客户端验证服务器证书
4. 客户端信任服务器后,和服务器协商对称密钥
5. 使用对称密钥开始通信

其中1~4的步骤都是TCP通信

hencoder/HTTPS的连接

  1. 附带随机数(后续用来计算密钥)、TLS版本、Cipher Suite(加密套件(打包一起发送的):可支持什么对称加密算法、非对称加密算法、Hash算法)

  2. Server Hello(服务器返回“好的”)
    服务器把它确定的TLS版本、Cipher [ˈsaɪfər] Suite,再附带服务端的随机数、客户端随机数返回

  3. 服务器证书信任建⽴(服务器附带证书)
    (用来给客户端验证是否是它要访问的服务器)
    包含:
    服务器地址、服务器名称等
    证书公钥(是核心。是非对称加密的公钥)
    证书签名(证明信息是真实的,不是别人模拟的)
    证书机构的公钥及其他信息(证明证书签名是这个证书机构颁发的这条信息是真实的)
    证书机构的签发方的信息(证明证书机构的信息是这个签发方签发的的这条信息是真实的)
    网站HTTPS证书结构

    其中证书签发方的真实性是可靠的(需要无条件信任),每个系统内都有“系统根证书”列表
    根证书列表是操作系统研发方验证后放在系统中的(只要操作系统、浏览器不被干掉就是安全的)

    证书的校验过程

  4. Pre-master Secret

    唯一一次非对称加密传过去的随机数
    服务端随机数、客户端随机数、pre-master Secret,这三个随机数通过算法计算出 Master secret,用Master secret计算对称加密的密钥
    Master Secret(由客户端加密密钥、服务端加密密钥、客户端MAC Secret、服务端MAC Secret生成)(客户端发送消息用客户端加密密钥加密,服务端发送消息用服务端加密密钥加密)(MAC Secret是用来验证身份的)

    PS:HMAC:Hash-based Message Authenticate Code,改良版的hash(HMAC(a)=MD5(fun(a))=c即中间经过一些变换,使得MD5加密后得到的hash值不容易被破解,而且这个转换只有通信两方知道,要用MAC Secret来参与转换,最终保证这个消息的真实性)

  5. 客户端通知:我要使⽤加密通信了

  6. 客户端发送:Finished
    其中的内容包含前面那些密钥、Finished消息,用客户端MAC Secret进行hash

  7. 服务器通知:我要使⽤加密通信了

  8. 服务器发送:Finished
    服务端发送的消息包含了前面的1~6的内容和它要发送的Finished消息,再用服务端MAC Secret进行hash

最后:TCP只知道有应用层消息(如:“应⽤层消息:#@R#RTERT#$TWERT”)根本不知道是什么协议,客户端和服务端发送出来的都是这种的

Android 中使⽤ HTTPS

正常情况

直接使⽤

什么时候会不行?
  • 用的自签名证书(例如只用于内网的https)
  • 证书信息不全,缺乏证书机构信息
  • 什么操作系统比较旧,没有安装最新加入的根证书
怎么办?