网络基础
1. 注册功能前端到后端数据库这一套流程
HTTP 是一种无状态的协议,客户端每次发送请求时,首先要和服务器端建立一个连接,在请求完成后又会断开这个连接。优点:节省资源。缺点:无法判断用户是否同一个。
Cookie + Session 登录
Cookie 是服务器端发送给客户端的一段特殊信息,以文本的方式存放在客户端。
Session是客户端请求服务端,服务端会为这次请求开辟的一块内存空间
登录:服务器验证密码无误后,会创建 SessionId,并通过 Set-Cookie 头信息,将 SessionId 写入 Cookie 中。
再次请求页面时:会自动带上第一次登录时写入的 Cookie,比对 Cookie 中的 SessionId 和保存在服务器端的 SessionId 是否一致
缺点:大量的 SessionId会导致服务器压力过大,Cookie容易被 XSRF(跨站请求伪造)攻击。所以适合于简单的后端架构,由开发人员维护好安全问题。
防止XSRF攻击措施:
- 涉及到数据修改操作严格使用 post 请求而不是 get 请求
- 显示验证方式:添加验证码、密码等
- 请求地址添加 token ,使黑客无法伪造用户请求
Token 登录
Token 是服务端生成的一串字符串
当第一次登录后,服务器会生成一个 Token 并返回给客户端,由客户端自由保存
客户端后续访问时,只需带上这个 Token 即可完成身份认证
优点:服务器不需存放token,token可以保存到如localstorage更安全的地方
缺点:在生效时间内一直有效,不好回收。
SSO 单点登录
内部搭建一个公共的认证中心,一个产品在认证中心登录后,再去访问另一个产品,可以不用再次登录。
初次请求时:会重定向到认证中心,并带上回调地址?return_uri=a.com/pageA,以便登录后直接进入对应页面。在认证中心输入账号密码提交登录,然后重定向a.com?ticket=123带上授权码 ticket,并将认证中心的登录态写入 Cookie。a.com服务器中,拿着 ticket 向认证中心确认,授权码 ticket 真实有效,成功后,服务器将登录信息写入 Cookie。
再次请求时:由于a.com存在已登录的 Cookie 信息,所以服务器端直接认证成功。
其他子页面请求时:会重定向到认证中心,但由于认证中心存在之前登录过的 Cookie,直接下发 ticket 给b.com即可。
子页面退出登录:清空c.com中的登录态 Cookie,请求认证中心通过tiket退出该api
优点:多产品的登录态共享,适合中大型企业统一内部产品的登录方式。
OAuth 第三方登录
微信开放平台流程:
首先,a.com的运营者需要在微信开放平台注册账号,并向微信申请使用微信登录功能,得到申请的 appid、appsecret。
用户在a.com上选择使用微信登录,会跳转微信的 OAuth 授权登录,并带上a.com的回调地址。输入微信账号和密码,登录成功后,微信会带上一个临时票据 code。a.com会拿着 code 、appid、appsecret,向微信服务器申请 token,验证成功后,微信会下发一个 token。
a.com就可以凭借 token 拿到对应的微信用户头像,用户昵称等信息了。此时提示用户登录成功,并将登录状态写入 Cookie,以作为后续访问。
优点:对于小企业可以借第三方平台登录开箱即用。
2. Http链接建立过程
先通过域名系统(DNS)查询将域名转换为 IP 地址
通过三次握手(稍后会讲)建立 TCP 连接
发起 HTTP 请求(报文),服务器接收到 HTTP 请求并处理
服务器往浏览器发回 HTTP 响应(报文),浏览器解析并渲染页面
关闭:四次挥手,默认情况下建立 TCP 连接不会断开,只有在请求报头中声明 Connection: close 才会在请求完成后关闭连接。
TCP链接的三次握手:SYN – 连接建立标记位,ACK – 确认标记位
- 客户端发送SYN标记包(Seq = x),进入SYN_SEND状态
- 服务器返回ACK应答,ACK = x + 1表示确认收到,同时发回一个SYN包(Seq=y)问客户端有没收到。进入SYN_RCVD状态
- 客户端再次发送ACK = y + 1,表示确认收到服务器的包,然后进入ESTABLISHED状态。服务端收到后也进入ESTABLISHED状态
TCP断开的四次挥手:FIN – 连接拆除标记位,ACK – 确认标记位
- 客户端发送一个FIN(Seq = x)标记的包,告诉服务器需要关闭连接,但是还可以接收数据.
- 服务端发送一个ACK=x+1的确认包,告诉客户端接收到关闭的请求,但是还没有准备好,要确认数据有没发送完。
- 服务端准备好关闭连接时,发送FIN标记的包(Seq = y),告诉客户端准备关闭了
- 客户端接收到服务端的关闭请求,再发送ACK=y+1的确认包,进入TIME_WAIT状态,等待服务端可能请求重传的ACK包。服务端接收到ACK包后,关闭连接,进入CLOSED状态。客户端在等待固定时间后,没有接收到服务的ACK包,认为服务器已关闭连接,自己也关闭连接,进入CLOSED状态。
3. Https连接建立过程
HTTPS 连接建立过程和 HTTP 差不多,区别在于 HTTP(默认端口 80) 请求只要在 TCP 连接建立后就可以发起,而 HTTPS(默认端口 443) 在 TCP 连接建立后,还需要经历 SSL 协议握手,成功后才能发起请求。
使用 HTTPS 时,所有的 HTTP 请求和响应数据在发送之前,都要进行加密。加密可以使用 SSL 或 TLS。
4. Http2
HTTP/2 是 HTTP/1.x 的扩展,而非替代。现在的主流浏览器 HTTP/2 的实现都是基于 SSL/TLS 的,也就是说使用 HTTP/2 的网站都是 HTTPS 协议的。
新增:
- HTTP 2.0 增加了新的二进制分帧数据层,通过流可以实现http请求和响应多路复用,和控制资源分配。
- HTTP/2 新增的一个强大的新功能,就是服务器可以对一个客户端请求发送多个响应,而无需客户端明确地请求。
- HTTP/2 可以对首部进行压缩。
5. UDP (用户数据报协议)
UDP 提供了无连接的数据报服务
缺点:UDP将数据从源端发送到目的端时,无需事先建立连接,没有使用TCP中的确认技术或滑动窗口机制,因此UDP不能保证数据传输的可靠性,也无法避免接收到重复数据的情况。需要应用程序提供报文的到达确认、排序和流量控制等功能。
优点:当应用程序对传输的可靠性要求不高,但是对传输速度和延迟小要求较高时,可以用UDP协议来替代TCP协议在传输层控制数据的转发。UDP适合于实时数据传输,如语音和视频通信,因为它们即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。
TCP和UDP区别:
1.TCP 是面向连接的传输控制协议,而UDP 提供了无连接的数据报服务;
2.TCP 具有高可靠性,确保传输数据的正确性,不出现丢失或乱序;UDP 在传输数据前不建立连接,不对数据报进行检查与修改,无须等待对方的应答,所以会出现分组丢失、重复、乱序,应用程序需要负责传输可靠性方面的所有工作;
3.UDP 具有较好的实时性,工作效率较 TCP 协议高;
4.UDP 段结构比 TCP 的段结构简单,因此网络开销也小。
6. 跨域
跨域是由于同源策略的一种约定,它是浏览器最核心也最基本的安全功能,防止受到XSS、CSRF等攻击。同源是指"协议+域名+端口"三者相同。跨域并不是请求发不出去,请求能发出去,服务端能收到请求并正常返回结果,只是结果被浏览器拦截了。
有三个标签是允许跨域加载资源:
- <img src='xxx'>
- <link href='xxx'>
- <script src='xxx'>
常用的跨域方案有:
Cors:
浏览器会自动进行 CORS 通信,只要后端实现了 CORS,就实现了跨域。
服务端设置 Access-Control-Allow-Origin 就可以开启 CORS。 该属性表示哪些域名可以访问资源,如果设置通配符则表示所有网站都可以访问资源。
Node中间件代理:
同源策略是浏览器需要遵循的标准,而如果是服务器向服务器请求就无需遵循同源策略。
通过node服务器代理客户端,就可以突破限制和"目标服务器"进行交互。例如vue项目中配置proxy代理。
nginx反向代理:
需要你搭建一个中转nginx服务器,用于转发请求。支持所有浏览器,支持session,不需要修改任何代码,并且不会影响服务器性能。
实现思路:通过nginx配置一个代理服务器(域名与domain1相同,端口不同)做跳板机,反向代理访问domain2接口,并且可以顺便修改cookie中domain信息,方便当前域cookie写入,实现跨域登录。
Jsonp:
利用<script>标签没有跨域限制的漏洞,网页可以得到从其他来源动态产生的JSON 数据。JSONP请求一定需要对方的服务器做支持才可以。
缺点是仅支持get方法具有局限性, 不安全可能会遭受XSS攻击。现在不常用。
7. 前后端实时通信
WebSocket:
WebSocket 是 HTML5 开始提供的一种在单个TCP连接上进行的双向通信协议,浏览器和服务器只需要一次握手,WebSocket 的 server 与 client就可以进行持续的,双向的数据传输,因此能显著节约资源和带宽。
WebSocket 在建立连接时需要借助 HTTP 协议,连接建立后就与 HTTP 无关了。
原生WebSocket API使用起来不太方便,我们使用Socket.io,它很好地封装了webSocket接口,提供了更简单、灵活的接口,也对不支持webSocket的浏览器提供了向下兼容。
缺点:
1. 兼容性问题:不支持较低版本的IE浏览器(IE9及以下)
2. 不支持断线重连,需要手写心跳连接的逻辑
3. 通信机制相对复杂
Websocket建立链接的过程:
1、客户端发送GET 请求,Upgrade: websocket ,告诉服务器
2、服务器收到协议,返给客户端switching protocol,就链接成功了
3、就进行了webSocket的通信了
AJAX轮询:
- 优点:兼容性良好,对标低版本IE
- 缺点:请求中有大半是无用的请求,浪费资源