网络安全三原则在传输过程中,用户隐私数据不允许明文传输;本地不允许以明文形式保存用户隐私数据;服务器上不允许以明文形式保存用户隐私数据;http是明文传输,wifi、路由器、运营商、机房等物理设备节点,如果中间的任何一个节点被监听,传输的内容就会完全暴露。在网络方面,我们知道POST请求和GET请求都会被捕获。如果不使用HTTPS,我们无法阻止抓包。如果用户隐私以明文形式传输,后果就不说了。很多用户密码是通用的,一旦被不法分子盗用,就会去其他网站与数据库碰撞,造成损失。如前所述,http传输存在三大风险:窃听风险(easdropping):第三方可以获悉通信内容。篡改风险(tampering):第三方可以修改通讯内容。假装:第三方可能假装成其他人参与通信。所以说到httpshttps可以认为是http+TLSTLS是一种传输层加密协议,它的前身是SSL协议,如果不特别说明,SSL和TLS指的是同一个协议。加密传输(避免明文传输)1.对称加密加解密使用同一个密钥在客户端和服务端进行通信,采用对称加密,如果只使用一个密钥,很容易被破解;如果每次都使用不同的密钥,海量秘钥的管理和传输成本会比较高。2、非对称加密需要加密和解密两把钥匙。这两个秘钥就是公钥(publickey,简称公钥)和私钥(privatekey,简称私钥)。非对称加密的模式那么:乙方生成两个密钥(公钥和私钥)。公钥是公开的,任何人都可以获得,而私钥是保密的。甲方获得乙方的公钥,然后用它来加密信息。乙方获得加密信息,用私钥解密。但是当服务端要返回数据的时候,如果是用公钥加密的,那么客户端是没有私钥解密的,如果是用私钥加密的,虽然客户端有公钥可以解密它,公钥之前已经在网上传过了,很可能已经有人拿到了,是不安全的,所以这个过程不能只用非对称加密来满足。(严格来说,私钥不能用于加密,只能作为签名。这是因为密码学中生成公私钥时,对不同变量的数学要求是不同的,所以公私钥是抗性的攻击能力也不同)所以为了满足即使是非对称的HTTPS,HTTPS的出发点也是解决HTTP明文传输过程中的信息篡改和监听问题。为了兼顾性能和安全性,采用了非对称加密+对称加密的方案。为了保证公钥在传输过程中不被篡改,使用了非对称加密的数字签名功能,通过CA机构和系统根证书的机制来保证HTTPS证书的可信度。只传递证书、明文信息、签名加密的明文信息,注意不要传递CA公钥(防止中间人攻击),客户端浏览器可以通过系统根证书获取CA公钥.(系统或浏览器中内置的CA组织的证书和公钥已经成为至关重要的一环)加密存储不要以明文形式存储密码如果以明文形式存储密码(无论是存储在数据库中还是日志中),一旦数据泄露,所有用户的密码都会毫无保留地暴露给黑客,可能会出现开头提到的风险,所以我们花很长时间加密传输密码是没有意义的。综上所述,如果我们想要尽可能的保证用户信息的安全,我们需要做好以下工作。使用https请求,使用RSA加密密码传输数据,使用BCrypt或PBKDF2单向加密,存储强制使用??HTTPS。有的网站购买了SSL证书,将其配置在Web服务器上,以为事情就这样结束了。但这只是表明您启用了HTTPS选项,用户很可能不会注意到。为确保每个用户都能从HTTPS中受益,您应该将所有传入的HTTP请求重定向到HTTPS。这意味着任何访问您网站的用户都将自动切换到HTTPS,他们的信息传输从此将是安全的。加上cookie的secure参数,禁止在最初的http请求中取出cookie(被中间人拦截)。TCP三向握手和四向握手Tcp是传输控制协议(TransmissionControlProtocol),专门设计用于在不可靠的Internet网络上提供可靠的端到端字节流的传输协议第一次握手:请求连接客户端->SYN=1,randomseq=x(数据包第一个字节的序号)第二次握手:同意回答,SYN和ACK都置1,ack=x+1,randomseq=y,returnto确认连接第三次握手:client检查ack是否为x+1,ACK为1,如果正确,标志位ACK置1,ack=y+1;——>Server,Server检查ack是否为y+1,ACK是否为1,正确则连接成功!Authentication授权+浏览器存储什么是Authentication?验证当前用户的身份,证明“你是你自己”互联网中的认证:用户名和密码,登录邮箱,发送登录链接,手机号,接收验证码,什么是AuthorizationUser授权第三方应用访问用户安装手机应用时的某些资源(是否允许访问相册、地理位置等)登录微信小程序(是否允许访问昵称、头像、地区、性别等个人信息))实现授权的方式有:cookie、session、token、OAuth什么是Credentials?认证授权的前提是需要一个介质(证书)来标识访问者的身份。登录成功后,服务器向用户使用的浏览器颁发一个token。,表明您的身份并在每次请求时随身携带。什么是饼干?HTTP是一种无状态协议。每个请求都是完全独立的。服务器无法确认当前访问者的身份信息,无法判断上次请求的发送者是否与本次发送者为同一人。因此,为了进行会话跟踪(知道谁在访问我),服务器和浏览器必须主动维护一个状态,用于通知服务器前后两次请求是否来自同一个浏览器。而这个状态需要通过cookie或者session来实现。Cookie存储在客户端:Cookie是服务器发送给用户浏览器并存储在本地的一小段数据。下次浏览器再次向同一服务器发出请求时,它会被携带并发送给服务器。Cookies是不跨域的:每个cookies都会绑定一个域名,不能在其他域名下使用。一级域名和二级域名之间允许共享使用(根据域名特性:cookie的大小有限制,一般为4KB;同一域名下cookie的存储数量有限制,以及不同浏览器数量不同,一般为20个;Cookies支持设置过期时间,过期自动销毁;(max-age,单位秒,如果为负数,浏览器将禁用临时cookies;默认为-1)每次发起同域下的HTTP请求,都会携带当前域名下的cookie;支持设置为HttpOnly,防止cookie被客户使用什么是JavaScript访问在客户端?Session会话是另一种记录服务器和客户端会话状态的机制。Bridge,大部分系统也是根据这个原理验证用户登录状态。什么是localStorage?特点是c大小限制在5MB~10MB;数据在同一来源的所有选项卡和窗口之间共享;数据只保存在客户端,不与服务器通信;数据持久化,不会过期,重启浏览器后仍然存在;对数据的操作是同步的。什么是sessionStoragesessionStorage数据只存在于当前浏览器选项卡中;页面刷新后数据仍然存在,但关闭浏览器选项卡后,数据会被清除;与localStorage有统一的API接口;对数据的操作是同步的。什么是令牌?访问资源接口(API)所需的资源凭证很简单token的组成:uid(用户的唯一标识),time(当前时间的时间戳),sign(签名,签名的前几位)token通过哈希算法压缩成一定长度的十六进制字符串)特点:服务器无状态,可扩展。它支持移动设备安全。支持跨程序调用。什么是智威汤逊?JSONWebToken(简称JWT)是目前最流行的跨域认证方案。(不使用cookies)方式:通过授权;通过网址;跨域时,可以将JWT放在POST请求的数据体中。与session和token不同的是JWT已经包含了用户信息,所以不需要去数据库查询,还有什么是XSSCross-SiteScripting(跨站脚本攻击),是一种代码注入攻击存储(数据库中任何可以输入存储的地方,注入脚本,服务器渲染时将脚本返回给浏览器)反射率(脚本写入url,比如路由参数诱导用户点击,脚本拼接写入html,服务器渲染时返回给浏览器)DOM(脚本写入url,前端JavaScript提取URL中的恶意代码并执行)预防:cookie设置readOnly禁止js脚本访问cookie。前端服务器设置输入框的格式勾选转义HTML(存储、反射),改为纯前端渲染(存储、反射)。使用react避免前端render阶段innerHTML和outerHTML的XSS隐患使用.textContent,.setAttribute()。什么是CSRFCross-siterequestforgery(英文:Cross-siterequestforgery)用户登录了安全网站A,诱导用户访问网站B,B利用A获得的凭证访问A,绕过用户authentication1.登录可信网站A,在本地生成cookies。2.在不退出A的情况下访问危险网站B。预防:同源策略(originreferrer)tokensamesiteBase64编码origin是因为有些网络传输通道不支持所有字节,比如传统邮件只支持可见字符的传输,和ASCII码等控制字符不能通过邮件传输。Base64是一种基于64个可打印字符来表示二进制数据的表示方法。ASCII码在计算机中,所有数据在存储和计算时都必须用二进制数表示,a、b、c、d等52个字母(包括大写)和0、1等数字和一些常用的符号(如*,#,@等)在计算机中存储时也应该用二进制数来表示,用于统一规定上述常用符号用哪些二进制数来表示unicode、utf-8、ASCII、base64,hashmd5ASCII美国信息交换标准码,用一个字节存储128个字符(包括33个控制字符(具有某些特殊功能但不能显示的字符)原因:在计算机中,所有数据的存储和计算都必须使用二进制数字表示(因为计算机用高电平和低电平分别表示1和0),例如52个字母(包括大写字母)如a、b、c、d,以及数字如0、1和一些常用的符号(如*、#、@等)也重新存入计算机时以二进制数表示,用哪些二进制数表示哪些符号。当然,每个人都可以约定自己的一套(这叫做编码),而如果每个人都想相互交流而不引起混淆,那么每个人都必须使用相同的编码规则,所以美国相关的标准化组织发布了ASCII编码,统一规定用哪些二进制数来表示上述常用符号[2]。Base64是网络上传输8Bit字节码最常用的一种编码方式。Base64是一种基于64个可打印字符表示二进制数据的方法。.base64编码是一个从二进制到字符浏览器的过程工作原理异步编程与同步编程相反。异步可以理解为异步操作完成后要做的任务。它们通常以回调函数或Promise的形式放入事件队列中,然后每次执行事件循环(EventLoop)机制。轮询时检查异步操作是否完成。如果完成,则按照事件队列中的执行规则依次执行相应的任务。javascript的运行机制(单线程、任务队列、EventLoop、microtask、macrotask)单线程特性single-threaded可以避免多线程操作带来的复杂的同步问题。任务队列(JavaScript运行机制)所有的同步任务都在主线程上执行,形成一个执行栈。在主线程之外,还有一个“任务队列”(taskqueue)。只要异步任务有运行结果,就会在“任务队列”中放入一个事件。一旦“执行栈”中的所有同步任务都执行完毕,系统就会读取“任务队列”,看看里面有什么事件。那些对应的异步任务结束等待状态,进入执行栈,开始执行。EventLoop会在每个Tick检查任务队列中是否有需要执行的任务。每个Tick的过程就是检查是否有未决事件,如果有则取出相关事件和回调函数放入执行栈中,供主线程执行。要处理的事件将存储在任务队列中。1.onclick是由浏览器内核的DOMBinding模块处理的。当事件被触发时,回调函数会立即加入到任务队列中。2、setTimeout会被浏览器内核的timer模块延时。当时间到了,回调函数将被添加到任务队列中。3.ajax会被浏览器内核的网络模块处理,网络请求完成返回后回调会加入到任务队列中。JavaScript是单线程的,而浏览器是多线程的。进程和线程都是操作系统的概念。进程是应用程序的执行实例。每个进程都由私有虚拟地址空间、代码、数据和各种其他系统资源组成。即进程是一个分配资源的操作系统,是独立的。最小的操作单元。进程(process)进程是一个应用程序的执行实例。每个进程都由私有虚拟地址空间、代码、数据和各种其他系统资源组成。即进程是操作系统进行资源分配和独立运行的最小单位。当我们启动一个应用程序时,计算机会创建至少一个进程,CPU会为该进程分配一部分内存。应用程序的所有状态都将存储在该内存中。应用程序还可以创建多个线程来协助工作。这些线程可以共享内存中的这部分数据。如果应用程序关闭,进程将终止,操作系统将释放关联的内存。线程(thread)进程内部的执行单元,是系统独立调度调度的基本单元。系统创建进程后,实际上是启动了执行该进程的主执行线程。进程就像一个有边界的生产工厂,而线程就像工厂里的员工,可以做自己的事情。它们也可以相互协作做同一件事,所以一个进程可以创建多个线程。线程本身不需要系统重新分配资源,它与属于同一进程的其他线程共享当前进程拥有的所有资源。PS:进程之间不共享资源和地址空间,所以不会有太多的安全问题,而且由于多个线程共享相同的地址空间和资源,可能会出现恶意修改或者访问未经授权的数据等复杂的安全问题。Chrome采用多进程架构。主进程是浏览器进程。浏览器主进程(负责协调和总控)(1)负责包括地址栏、书签栏、前进后退按钮等工作(2)负责处理浏览器一些不可见的部分底层网络请求、文件访问等操作(3)负责管理各个页面,创建和销毁其他进程.PluginProcess负责控制一个网页中使用的所有插件,比如flash,每一种插件对应一个进程,只有在使用插件的时候,GPUProcess才负责处理GPU-相关任务,3D绘图等。由于默认打开一个新的标签页,创建一个新的进程,所以单个标签页崩溃不会影响整个浏览器。同样,第三方插件崩溃不会影响整个浏览器。多处理可以充分利用现代CPU的多核优势。缺点系统为浏览器新打开的进程分配内存、CPU等资源,因此内存和CPU的资源消耗会更大。不过Chrome在内存释放方面做的很好,基本的内存可以快速释放出来供其他程序运行。浏览器至少实现了三个常驻线程:JavaScript引擎线程、GUI渲染线程和浏览器事件触发线程。1.JavaScript引擎基于事件驱动的单线程执行。JavaScript引擎一直在等待任务队列中任务的到来,然后进行处理。浏览器在任何时候都只有一个JavaScript线程运行JavaScript程序。2、GUI渲染线程负责渲染浏览器界面。当界面需要重绘(Repaint)或者由于某种操作导致回流(Reflow)时,线程就会执行。但是需要注意的是,GUI渲染线程和JavaScript引擎是相互排斥的。当JavaScript引擎执行时,GUI线程会被挂起,GUI更新会保存在一个队列中,当JavaScript引擎空闲时立即执行。3.事件触发线程,当有事件被触发时,该线程会将事件添加到待处理队列的末尾,等待JavaScript引擎处理。这些事件可以来自JavaScript引擎当前执行的代码块如setTimeout,也可以来自浏览器内核的其他线程如鼠标点击、Ajax异步请求等,但由于JavaScript的单线程关系,都这些事件必须排队等待JavaScript引擎处理(异步代码只有在线程中没有执行同步代码时才会执行)问题为什么Javascript是单线程的?JavaScript用于处理页面上的用户交互,并操纵DOM树和CSS样式树向用户呈现动态视图。丰富的交互体验和服务端逻辑的交互处理。如果JavaScript以多线程的方式操作这些UIDOM,可能会出现UI操作冲突。但是为了避免锁的引入带来更大的复杂度,Javascript一开始就选择了单线程执行。为什么JS会阻塞页面加载?由于JavaScript可以操作DOM,如果在修改这些元素属性的同时渲染界面(即JavaScript线程和UI线程同时运行),渲染线程前后获取的元素数据可能不一致。因此,为了防止不可预测的渲染结果,浏览器将GUI渲染线程和JavaScript引擎设置为互斥。css加载会不会阻塞?CSS加载不会阻塞DOM的解析(并行),RenderTree依赖DOMTree和CSSOMTree,所以CSS加载会阻塞Dom的渲染,css会阻塞后续js的执行什么是CRP,CriticalRendering路径(CriticalRenderingPath)渲染路径)?如何优化?html可以一步步解析,和css解析并行,css不行,因为css的每一个属性都可以改变cssom,比如后者覆盖了前面设置的font-size等,所以必须等到在进入下一阶段之前构建cssom。CSS的加载速度和构建CSSOM的速度会直接影响首屏的渲染速度,因此CSS默认被视为渲染阻塞资源。通常DOM和CSSOM是并行构建的,但是当浏览器遇到脚本标签时,DOM构建将暂停,直到脚本执行完毕。但是由于JavaScript可以修改CSSOM,所以需要等待CSSOM构建完成后才能执行JS。围绕三个因素(js、css)关键路径长度和关键字节数优化关键资源数量(字节越小,下载和处理速度越快-压缩)具体方法:优化domhtml文件为小尽可能删除冗余代码,压缩代码,使用缓存(http缓存)优化cssom,只将首屏需要的css通过style标签嵌入到头部,其余使用异步非阻塞加载(如CriticalCSS)避免使用@import@import将css引入从并行加载到串行加载异步js所有文本资源尽可能小,删除无用代码,减小文件大小(Minify),使用gzip压缩(Compress),使用缓存(HTTPCache)可以在脚本中添加async属性实现异步加载5.浏览器输入url渲染的过程。解析HTML文件并构建DOM树。同时,浏览器主进程负责下载CSS文件。下载CSS文件后,将CSS文件解析成树状数据结构,再将DOM树组合成RenderObject树。RenderObject树的布局(Layout/reflow)负责计算RenderObject树中元素的大小和位置绘制RenderObject树(paint),绘制页面的像素信息浏览器的主要流程会交给defaultlayer和compositelayer交给GPU进程,GPU进程会合成每一层(composite),最后页面6.EventLoop至少包含两个队列。宏任务队列和微任务队列async/await成对出现。标有async的函数会返回一个Promise对象,可以使用then方法添加回调函数。await之后的语句会被同步执行。但是await下面的语句会作为microtask加入到当前任务队列的尾部,异步执行。Microbeforemacroreflow(Reflow)当RenderTree中部分或全部元素的大小、结构或某些属性发生变化时,浏览器重新渲染部分或全部文档的过程称为回流。引起回流的操作:页面第一次渲染浏览器窗口大小改变元素大小或位置改变元素内容改变(文本数量或图片大小等)元素字体大小改变添加或移除可见的DOM元素激活CSS伪类(eg::hover)查询某些属性或调用某些方法进行重绘(Repaint)当页面中元素样式的改变不影响其在文档流中的位置时(对于example:color,background-color,visibility,etc.),browserenderer会把新的样式赋值给元素并重新绘制,这个过程叫做重绘。回流比重绘更昂贵。有时即使只有一个元素被回流,它的父元素和它后面的任何元素也会回流。多线程的优点和缺点是什么?优点:1、在子线程中执行耗时操作(网络请求、图片下载、音频下载、数据库访问等),可以防止主线程被卡住;CPU使用率。缺点:1、每次开启子线程,都会消耗一定的资源;2、代码的可读性会变差;3.如果多个线程同时访问一个资源,就会发生资源争用。
