整合營(yíng)銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          聽(tīng)說(shuō)你的資源被盜用了,那你知道 Nginx 怎么防盜鏈嗎?

          單有效的防盜鏈?zhǔn)侄?/p>

          場(chǎng)景

          如果做過(guò)個(gè)人站點(diǎn)的同學(xué),可能會(huì)遇到別人盜用自己站點(diǎn)資源鏈接的情況,這就是盜鏈。說(shuō)到盜鏈就要說(shuō)一個(gè) HTTP 協(xié)議的 頭部,referer 頭部。當(dāng)其他網(wǎng)站通過(guò) URL 引用了你的頁(yè)面,用戶在瀏覽器上點(diǎn)擊 URL 時(shí),HTTP 請(qǐng)求的頭部會(huì)通過(guò) referer 頭部將該網(wǎng)站當(dāng)前頁(yè)面的 URL 帶上,告訴服務(wù)器本次請(qǐng)求是由誰(shuí)發(fā)起的。

          例如,在谷歌中搜索 Nginx 然后點(diǎn)擊鏈接:

          在打開(kāi)的新頁(yè)面中查看請(qǐng)求頭會(huì)發(fā)現(xiàn),請(qǐng)求頭中包含了 referer 頭部且值是 https://www.google.com/。

          像谷歌這種我們是允許的,但是有一些其他的網(wǎng)站想要引用我們自己網(wǎng)站的資源時(shí),就需要做一些管控了,不然豈不是誰(shuí)都可以拿到鏈接。

          目的

          這里目的其實(shí)已經(jīng)很明確了,就是要拒絕非正常的網(wǎng)站訪問(wèn)我們站點(diǎn)的資源。

          思路

          • invalid_referer 變量referer 提供了這個(gè)變量,可以用來(lái)配置哪些 referer 頭部合法,也就是,你允許哪些網(wǎng)站引用你的資源。

          referer 模塊

          要實(shí)現(xiàn)上面的目的,referer 模塊可得算頭一號(hào),一起看下 referer 模塊怎么用的。

          • 默認(rèn)編譯進(jìn) Nginx,通過(guò) --without-http_referer_module 禁用

          referer 模塊有三個(gè)指令,下面看一下。

          Syntax: valid_referers none | blocked | server_names | string ...;
          Default: —
          Context: server, location
          
          Syntax: referer_hash_bucket_size size;
          Default: referer_hash_bucket_size 64; 
          Context: server, location
          
          Syntax: referer_hash_max_size size;
          Default: referer_hash_max_size 2048; 
          Context: server, location
          
          • valid_referers 指令,配置是否允許 referer 頭部以及允許哪些 referer 訪問(wèn)。
          • referer_hash_bucket_size 表示這些配置的值是放在哈希表中的,指定哈希表的大小。
          • referer_hash_max_size 則表示哈希表的最大大小是多大。

          這里面最重要的是 valid_referers 指令,需要重點(diǎn)來(lái)說(shuō)明一下。

          valid_referers 指令

          可以同時(shí)攜帶多個(gè)參數(shù),表示多個(gè) referer 頭部都生效。

          參數(shù)值

          • none允許缺失 referer 頭部的請(qǐng)求訪問(wèn)
          • block:允許 referer 頭部沒(méi)有對(duì)應(yīng)的值的請(qǐng)求訪問(wèn)。例如可能經(jīng)過(guò)了反向代理或者防火墻
          • server_names:若 referer 中站點(diǎn)域名與 server_name 中本機(jī)域名某個(gè)匹配,則允許該請(qǐng)求訪問(wèn)
          • string:表示域名及 URL 的字符串,對(duì)域名可在前綴或者后綴中含有 * 通配符,若 referer 頭部的值匹配字符串后,則允許訪問(wèn)
          • 正則表達(dá)式:若 referer 頭部的值匹配上了正則,就允許訪問(wèn)

          invalid_referer 變量

          • 允許訪問(wèn)時(shí)變量值為空
          • 不允許訪問(wèn)時(shí)變量值為 1

          實(shí)戰(zhàn)

          下面來(lái)看一個(gè)配置文件。

          server {
          	server_name referer.ziyang.com;
              listen 80;
          
          	error_log logs/myerror.log debug;
          	root html;
          	location /{
          		valid_referers none blocked server_names
                         		*.ziyang.com www.ziyang.org.cn/nginx/
                         		~\.google\.;
          		if ($invalid_referer) {
              			return 403;
          		}
          		return 200 'valid\n';
          	}
          }
          
          

          那么對(duì)于這個(gè)配置文件而言,以下哪些請(qǐng)求會(huì)被拒絕呢?

          curl -H 'referer: http://www.ziyang.org.cn/ttt' referer.ziyang.com/
          curl -H 'referer: http://www.ziyang.com/ttt' referer.ziyang.com/
          curl -H 'referer: ' referer.ziyang.com/
          curl referer.ziyang.com/
          curl -H 'referer: http://www.ziyang.com' referer.ziyang.com/
          curl -H 'referer: http://referer.ziyang.com' referer.ziyang.com/
          curl -H 'referer: http://image.baidu.com/search/detail' referer.ziyang.com/
          curl -H 'referer: http://image.google.com/search/detail' referer.ziyang.com/
          

          我們需要先來(lái)解析一下這個(gè)配置文件。valid_referers 指令配置了哪些值呢?

           valid_referers none blocked server_names
                  *.ziyang.com www.ziyang.org.cn/nginx/
                  ~\.google\.;
          
          • none:表示沒(méi)有 referer 的可以訪問(wèn)
          • blocked:表示 referer 沒(méi)有值的可以訪問(wèn)
          • server_names:表示本機(jī) server_name 也就是 referer.ziyang.com 可以訪問(wèn)
          • *.ziyang.com:匹配上了正則的可以訪問(wèn)
          • www.ziyang.org.cn/nginx/:該頁(yè)面發(fā)起的請(qǐng)求可以訪問(wèn)
          • ~\.google\.:google 前后都是正則匹配

          下面就實(shí)際看下響應(yīng):

          # 返回 403,沒(méi)有匹配到任何規(guī)則
          ?  ~ curl -H 'referer: http://www.ziyang.org.cn/ttt' referer.ziyang.com/
          <html>
          <head><title>403 Forbidden</title></head>
          <body>
          <center><h1>403 Forbidden</h1></center>
          <hr><center>nginx/1.17.8</center>
          </body>
          </html>
          ?  ~ curl -H 'referer: http://image.baidu.com/search/detail' referer.ziyang.com/
          <html>
          <head><title>403 Forbidden</title></head>
          <body>
          <center><h1>403 Forbidden</h1></center>
          <hr><center>nginx/1.17.8</center>
          </body>
          </html>
          # 匹配到了 *.ziyang.com
          ?  ~ curl -H 'referer: http://www.ziyang.com/ttt' referer.ziyang.com/
          valid
          ?  ~ curl -H 'referer: http://www.ziyang.com' referer.ziyang.com/
          valid
          # 匹配到了 server name
          ?  ~ curl -H 'referer: http://referer.ziyang.com' referer.ziyang.com/
          valid
          # 匹配到了 blocked
          ?  ~ curl -H 'referer: ' referer.ziyang.com/
          valid
          # 匹配到了 none
          ?  ~ curl referer.ziyang.com/
          valid
          # 匹配到了 ~\.google\.
          ?  ~ curl -H 'referer: http://image.google.com/search/detail' referer.ziyang.com/
          valid
          

          防盜鏈另外一種解決方案:secure_link 模塊

          referer 模塊是一種簡(jiǎn)單的防盜鏈?zhǔn)侄危仨氁蕾嚍g覽器發(fā)起請(qǐng)求才會(huì)有效,如果攻擊者偽造 referer 頭部的話,這種方式就失效了。

          secure_link 模塊是另外一種解決的方案。

          它的主要原理是,通過(guò)驗(yàn)證 URL 中哈希值的方式防盜鏈。

          基本過(guò)程是這個(gè)樣子的:

          • 由服務(wù)器(可以是 Nginx,也可以是其他 Web 服務(wù)器)生成加密的安全鏈接 URL,返回給客戶端
          • 客戶端使用安全 URL 訪問(wèn) Nginx,由 Nginx 的 secure_link 變量驗(yàn)證是否通過(guò)

          原理如下:

          • 哈希算法是不可逆的
          • 客戶端只能拿到執(zhí)行過(guò)哈希算法的 URL
          • 僅生成 URL 的服務(wù)器,驗(yàn)證 URL 是否安全的 Nginx,這兩者才保存原始的字符串
          • 原始字符串通常由以下部分有序組成:資源位置。如 HTTP 中指定資源的 URI,防止攻擊者拿到一個(gè)安全 URI 后可以訪問(wèn)任意資源用戶信息。如用戶的 IP 地址,限制其他用戶盜用 URL時(shí)間戳。使安全 URL 及時(shí)過(guò)期密鑰。僅服務(wù)器端擁有,增加攻擊者猜測(cè)出原始字符串的難度

          模塊:

          • ngx_http_secure_link_module未編譯進(jìn) Nginx,需要通過(guò) --with-http_secure_link_module 添加
          • 變量secure_linksecure_link_expires
          Syntax: secure_link expression;
          Default: —
          Context: http, server, location
          
          Syntax: secure_link_md5 expression;
          Default: —
          Context: http, server, location
          
          Syntax: secure_link_secret word;
          Default: —
          Context: location
          

          變量值及帶過(guò)期時(shí)間的配置示例

          • secure_link值為空字符串:驗(yàn)證不通過(guò)值為 0:URL 過(guò)期值為 1:驗(yàn)證通過(guò)
          • secure_link_expires時(shí)間戳的值

          命令行生成安全鏈接

          • 生成 md5
          echo -n '時(shí)間戳URL客戶端IP密鑰' | openssl md5 -binary | openssl base64 | tr +/ - | tr -d =
          
          • 構(gòu)造請(qǐng)求 URL
          /test1.txt?md5=md5生成值&expires=時(shí)間戳(如 2147483647)
          

          Nginx 配置

          • secure_link $arg_md5,$arg_expires;secure_link 后面必須跟兩個(gè)值,一個(gè)是參數(shù)中的 md5,一個(gè)是時(shí)間戳
          • secure_link_md5 "$secure_link_expires$uri$remote_addr secret";按照什么樣的順序構(gòu)造原始字符串

          實(shí)戰(zhàn)

          下面是一個(gè)實(shí)際的配置文件,我這里就不做演示了,感興趣的可以自己做下實(shí)驗(yàn)。

          server {
          	server_name securelink.ziyang.com;
              listen 80;
          	error_log  logs/myerror.log  info;
          	default_type text/plain;
          	location /{
          		secure_link $arg_md5,$arg_expires;
                  secure_link_md5 "$secure_link_expires$uri$remote_addr secret";
          
                  if ($secure_link = "") {
                      return 403;
                  }
          
                  if ($secure_link = "0") {
                      return 410;
                  }
          
          		return 200 '$secure_link:$secure_link_expires\n';
          	}
          
          	location /p/ {
                  secure_link_secret mysecret2;
          
                  if ($secure_link = "") {
                      return 403;
                  }
          
                  rewrite ^ /secure/$secure_link;
          	}
          
          	location /secure/ {
          		alias html/;
              	internal;
          	}
          }
          

          僅對(duì) URI 進(jìn)行哈希的簡(jiǎn)單辦法

          除了上面這種相對(duì)復(fù)雜的方式防盜鏈,還有一種相對(duì)簡(jiǎn)單的防盜鏈方式,就是只對(duì) URI 進(jìn)行哈希,這樣當(dāng) URI 傳

          • 將請(qǐng)求 URL 分為三個(gè)部分:/prefix/hash/link
          • Hash 生成方式:對(duì) “l(fā)ink 密鑰” 做 md5 哈希
          • 用 secure_link_secret secret; 配置密鑰

          命令行生成安全鏈接

          • 原請(qǐng)求link
          • 生成的安全請(qǐng)求/prefix/md5/link
          • 生成 md5echo -n 'linksecret' | openssl md5 –hex

          Nginx 配置

          • secure_link_secret secret;

          這個(gè)防盜鏈的方法比較簡(jiǎn)單,那么具體是怎么用呢?大家都在網(wǎng)上下載過(guò)資源對(duì)吧,不管是電子書(shū)還是軟件,很多網(wǎng)站你點(diǎn)擊下載的時(shí)候往往會(huì)彈出另外一個(gè)頁(yè)面去下載,這個(gè)新的頁(yè)面其實(shí)就是請(qǐng)求的 Nginx 生成的安全 URL。如果這個(gè) URL 被拿到的話,其實(shí)還是可以用的,所以需要經(jīng)常的更新密鑰來(lái)確保 URL 不會(huì)被盜用。

          者:Java3y

          原文:轉(zhuǎn)載自微信公眾號(hào),Java3y

          前言

          只有光頭才能變強(qiáng)。

          文本已收錄至我的GitHub倉(cāng)庫(kù),歡迎Star:https://github.com/ZhongFuCheng3y/3y

          為什么要學(xué)HTTP?

          我們絕大多數(shù)的Web應(yīng)用都是基于HTTP來(lái)進(jìn)行開(kāi)發(fā)的。我們對(duì)Web的操作都是通過(guò)HTTP協(xié)議來(lái)進(jìn)行傳輸數(shù)據(jù)的。

          簡(jiǎn)單來(lái)說(shuō),HTTP協(xié)議就是客戶端和服務(wù)器交互的一種通迅的格式

          HTTP的誕生主要是為了能夠讓文檔之間相互關(guān)聯(lián),形成超文本可以互相傳閱

          可以說(shuō),Http就是Web通信的基礎(chǔ),這是我們必學(xué)的。

          HTTP基礎(chǔ)概念

          我們學(xué)計(jì)算機(jī)網(wǎng)絡(luò)的時(shí)候就知道,我們把計(jì)算機(jī)網(wǎng)絡(luò)分層了5層,一般我們現(xiàn)在用的都是TCP/IP這么一個(gè)分層結(jié)構(gòu)。

          雖然官方的是ISO 提出的7層結(jié)構(gòu),但是僅僅是理論基礎(chǔ),在實(shí)際上大多人都是使用TCP/IP的分層結(jié)構(gòu)

          首先,我們先得知道,為什么我們要在計(jì)算機(jī)網(wǎng)絡(luò)中分層次???

          因?yàn)槿绻麅膳_(tái)計(jì)算機(jī)能夠相互通信的話,實(shí)際實(shí)現(xiàn)起來(lái)是非常困難操作的…我們分層的目的就是為了將困難的問(wèn)題簡(jiǎn)單化,并且如果我們分層了,我們?cè)谑褂玫臅r(shí)候就可以僅僅關(guān)注我們需要關(guān)注的層次,而不用理會(huì)其他層

          如果需要改動(dòng)設(shè)計(jì)的時(shí)候,我們只需要把變動(dòng)的層替換即可,并不用涉及到其他的層次。這與我們程序設(shè)計(jì)中的低耦合是一個(gè)概念。

          而我們的HTTP協(xié)議是在最上層,也就是應(yīng)用層。這是最貼近我們的程序員的層次。

          網(wǎng)站通信粗略過(guò)程

          我們知道HTTP是在應(yīng)用層中的,顯然,我們?cè)赪eb通信的過(guò)程中,不僅僅是需要HTTP協(xié)議的,還會(huì)涉及到其他的協(xié)議的

          DNS:負(fù)責(zé)解析域名

          • 我們?cè)L問(wèn)一個(gè)網(wǎng)頁(yè)的時(shí)候,往往是通過(guò)域名來(lái)訪問(wèn)的www.zhongfucheng.site,而計(jì)算機(jī)通信只認(rèn)的是我們的主機(jī)地址(192.168.xxx.xxx),因此,當(dāng)我們輸入域名的時(shí)候,需要DNS把域名解析成主機(jī)來(lái)進(jìn)行訪問(wèn)。


          HTTP:產(chǎn)生請(qǐng)求報(bào)文數(shù)據(jù)

          • 當(dāng)我們對(duì)Web頁(yè)面進(jìn)行操作的時(shí)候,就會(huì)產(chǎn)生HTTP報(bào)文數(shù)據(jù),請(qǐng)求對(duì)應(yīng)的服務(wù)端進(jìn)行響應(yīng)。

          這里寫(xiě)圖片描述

          TCP協(xié)議:分割HTTP數(shù)據(jù),保證數(shù)據(jù)運(yùn)輸

          • TCP協(xié)議采用了三次握手的方式來(lái)保證數(shù)據(jù)的準(zhǔn)確運(yùn)輸,在運(yùn)輸?shù)臄?shù)據(jù)的時(shí)候,發(fā)送標(biāo)識(shí)過(guò)去給服務(wù)器,服務(wù)器也返回標(biāo)識(shí)給客戶端,而客戶端收到消息后再次返回標(biāo)識(shí)給服務(wù)器。這樣一來(lái)就保證了數(shù)據(jù)運(yùn)輸是可靠的。


          IP協(xié)議:傳輸數(shù)據(jù)包,找到通信目的地地址。

          • IP協(xié)議把我們的產(chǎn)生的數(shù)據(jù)包發(fā)送給對(duì)方,IP地址指明了節(jié)點(diǎn)被分配的地址,但I(xiàn)P地址可能會(huì)變換,我們可以使用ARP協(xié)議來(lái)將IP地址反射為MAC地址。MAC地址是不會(huì)更改的,是網(wǎng)卡所屬的固定地址。
          • 在找到通信目的地之前,我們是需要不斷的中轉(zhuǎn)的,這過(guò)程我們稱作為:“路由中轉(zhuǎn)”,我們并不知道路由中轉(zhuǎn)了多少次的。因此是不能全面了解到互聯(lián)網(wǎng)中的傳輸狀況的。


          接下來(lái)就離我們比較遠(yuǎn)了,屬于硬件相關(guān)的了,也就是鏈路層和物理層。以后復(fù)習(xí)到計(jì)算機(jī)網(wǎng)絡(luò)的時(shí)候再來(lái)補(bǔ)充吧!

          我們網(wǎng)頁(yè)上請(qǐng)求數(shù)據(jù)就是上邊這么一個(gè)流程

          告知服務(wù)器請(qǐng)求的意圖

          我們?nèi)绻_(kāi)發(fā)過(guò)Web程序的話,我們知道常用的提交方式有POST和GET方法

          我們也知道GET是用來(lái)獲取數(shù)據(jù)的,POST是用來(lái)提交數(shù)據(jù)的。

          其實(shí)HTTP協(xié)議中還支持著其他的方法,比如:Input、Delete、OPTIONS很多這樣的方法。而由于常用,于是我們也可能僅僅知道GET和POST方法了。

          HTTP提供方法的目的就是為了告知服務(wù)器該客戶端想進(jìn)行什么操作。當(dāng)HTTP是OPTIONS方法的時(shí)候,服務(wù)器端就會(huì)返回它支持什么HTTP方法。

          當(dāng)然了,現(xiàn)在RESTful盛行,也就是充分利用了HTTP協(xié)議的這些方法

          HTTP是不保存狀態(tài)的協(xié)議

          HTTP是無(wú)狀態(tài)的,也就是說(shuō),它是不對(duì)通信狀態(tài)進(jìn)行保存的。它并不知道之前通信的對(duì)方是誰(shuí)。這樣設(shè)計(jì)的目的就是為了讓HTTP簡(jiǎn)單化,能夠快速處理大量的事務(wù)!

          但是,我們經(jīng)常是需要知道訪問(wèn)的人是誰(shuí),于是就有了Cookie技術(shù)了。

          • 要是服務(wù)器端想要記住客戶端是誰(shuí),那么就頒發(fā)一個(gè)cookie給客戶端
          • 客戶端把Cookie保存在硬盤(pán)中,當(dāng)下次訪問(wèn)服務(wù)器的時(shí)候,瀏覽器會(huì)自動(dòng)把客戶端的cookie帶過(guò)去。
          • 就這樣,服務(wù)器就能夠知道這家伙是誰(shuí)了。


          持久連接

          在HTTP1.0的時(shí)候,每一次進(jìn)行HTTP通信就會(huì)斷開(kāi)一次連接。如果容量很少的文本傳輸是沒(méi)有問(wèn)題的。但是如果我們?cè)L問(wèn)一個(gè)網(wǎng)頁(yè),該網(wǎng)頁(yè)有非常多的圖片。一個(gè)圖片就算上一個(gè)HTTP請(qǐng)求了。那么在中途中就不斷地建立TCP連接、獲取圖片、斷開(kāi)TCP連接。

          這樣是非常浪費(fèi)資源的,因此在HTTP1.1版本,就是持久連接了。一次HTTP連接能夠處理多個(gè)請(qǐng)求

          持久連接為“管線化”方式發(fā)送成為了可能:在一次HTTP連接里面,不需要等待服務(wù)器響應(yīng)請(qǐng)求,就能夠繼續(xù)發(fā)送第二次請(qǐng)求

          提升傳輸效率

          在說(shuō)明之前,首先我們要知道什么是實(shí)體主體

          • 實(shí)體主體就是作為數(shù)據(jù)在HTTP中傳輸?shù)臄?shù)據(jù)


          一般地,實(shí)體主體可以等價(jià)為報(bào)文主體,報(bào)文主體是HTTP中的一部分

          我們?nèi)绻皇褂萌魏问侄危?wù)器返回的數(shù)據(jù)實(shí)體主體是原樣返回的。我們可以使用兩種方式來(lái)提高傳輸效率

          • 使用壓縮技術(shù)把實(shí)體主體壓小,在客戶端再把數(shù)據(jù)解析
          • 使用分塊傳輸編碼,將實(shí)體主體分塊傳輸,當(dāng)瀏覽器解析到實(shí)體主體就能夠顯示了。

          我們?nèi)绻谙螺d東西的過(guò)程中斷了,按照以前我們是需要重新下載的,但是現(xiàn)在可以在中斷中繼續(xù)下載。我們可以使用到獲取范圍數(shù)據(jù),這種叫做范圍請(qǐng)求

          這種請(qǐng)求只會(huì)下載資源的一部分。

          • 比如我的圖片下載到一半了,我們只需要下載另一半就可以組成一張完整的圖片了。那么請(qǐng)求的時(shí)候請(qǐng)求沒(méi)有下載的一部分即可。


          常用的狀態(tài)碼簡(jiǎn)述

          2XX

          一般是請(qǐng)求成功

          200 正常處理

          204 成功處理,但服務(wù)器沒(méi)有新數(shù)據(jù)返回,顯示頁(yè)面不更新

          206 對(duì)服務(wù)器進(jìn)行范圍請(qǐng)求,只返回一部分?jǐn)?shù)據(jù)

          3XX

          一般表示重定向

          301 請(qǐng)求的資源已分配了新的URI中,URL地址改變了。【永久重定向】

          302 請(qǐng)求的資源臨時(shí)分配了新的URI中,URL地址沒(méi)變【轉(zhuǎn)發(fā)】

          303 與302相同的功能,但明確客戶端應(yīng)該采用GET方式來(lái)獲取資源

          304 發(fā)送了附帶請(qǐng)求,但不符合條件【返回未過(guò)期的緩存數(shù)據(jù)】

          307 與302相同,但不會(huì)把POST請(qǐng)求變成GET

          4XX

          表示客戶端出錯(cuò)了。

          400 請(qǐng)求報(bào)文語(yǔ)法錯(cuò)誤了

          401 需要認(rèn)證身份

          403 沒(méi)有權(quán)限訪問(wèn)

          404 服務(wù)器沒(méi)有這個(gè)資源

          5XX

          服務(wù)器出錯(cuò)了

          500 內(nèi)部資源出錯(cuò)了

          503 服務(wù)器正忙

          服務(wù)器與客戶端之間的應(yīng)用程序

          首先要說(shuō)的是,一個(gè)HTTP服務(wù)器可以擁有多個(gè)站點(diǎn),也就是說(shuō):HTTP下可以配置多個(gè)虛擬主機(jī)。當(dāng)用戶訪問(wèn)不同主機(jī)的時(shí)候,實(shí)際上都是訪問(wèn)同一臺(tái)HTTP服務(wù)器。

          在客戶端和服務(wù)器中還有一些用于通信數(shù)據(jù)轉(zhuǎn)發(fā)的應(yīng)用程序

          • 代理
          • 可以用來(lái)緩存數(shù)據(jù),當(dāng)代理緩存了數(shù)據(jù)以后,客戶端就可以直接用代理獲取數(shù)據(jù)
          • 可以用來(lái)對(duì)網(wǎng)站進(jìn)行訪問(wèn)控制,獲取訪問(wèn)日志記錄
          • 網(wǎng)關(guān)
          • 能夠提供非HTTP請(qǐng)求的操作,訪問(wèn)數(shù)據(jù)庫(kù)什么的
          • 隧道
          • 建立一條安全的通信路徑,可以使用SSL等加密手段進(jìn)行通信。

          HTTP首部簡(jiǎn)述

          HTTP請(qǐng)求報(bào)文

          HTTP請(qǐng)求報(bào)文:在請(qǐng)求中,HTTP報(bào)文由方法、URI、HTTP版本、HTTP首部字段等部分組成。

          1. 請(qǐng)求行【描述客戶端的請(qǐng)求方式請(qǐng)求的資源名稱,以及使用的HTTP協(xié)議版本號(hào)
          2. 首部字段【描述客戶端請(qǐng)求哪臺(tái)主機(jī),以及客戶端的一些環(huán)境信息等】
          3. 一個(gè)空行

          首部字段例子:

          • Accept: text/html,image/* 【瀏覽器告訴服務(wù)器,它支持的數(shù)據(jù)類型】
          • Accept-Charset: ISO-8859-1 【瀏覽器告訴服務(wù)器,它支持哪種字符集
          • Accept-Encoding: gzip,compress 【瀏覽器告訴服務(wù)器,它支持的壓縮格式
          • Accept-Language: en-us,zh-cn 【瀏覽器告訴服務(wù)器,它的語(yǔ)言環(huán)境】
          • Host: www.it315.org:80【瀏覽器告訴服務(wù)器,它的想訪問(wèn)哪臺(tái)主機(jī)】
          • If-Modified-Since: Tue, 11 Jul 2000 18:23:51 GMT【瀏覽器告訴服務(wù)器,緩存數(shù)據(jù)的時(shí)間】
          • Referer: http://www.it315.org/index.jsp【瀏覽器告訴服務(wù)器,客戶機(jī)是從那個(gè)頁(yè)面來(lái)的---反盜鏈
          • 8.User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)【瀏覽器告訴服務(wù)器,瀏覽器的內(nèi)核是什么】
          • Cookie【瀏覽器告訴服務(wù)器,帶來(lái)的Cookie是什么
          • Connection: close/Keep-Alive 【瀏覽器告訴服務(wù)器,請(qǐng)求完后是斷開(kāi)鏈接還是保持鏈接】
          • Date: Tue, 11 Jul 2000 18:23:51 GMT【瀏覽器告訴服務(wù)器,請(qǐng)求的時(shí)間】

          HTTP響應(yīng)報(bào)文

          HTTP響應(yīng)報(bào)文:在響應(yīng)中,HTTP報(bào)文由HTTP版本、狀態(tài)碼(數(shù)字和原因短語(yǔ))、HTTP首部字段3部分組成。

          1. 一個(gè)狀態(tài)行【用于描述服務(wù)器對(duì)請(qǐng)求的處理結(jié)果。
          2. 首部字段【用于描述服務(wù)器的基本信息,以及數(shù)據(jù)的描述服務(wù)器通過(guò)這些數(shù)據(jù)的描述信息,可以通知客戶端如何處理等一會(huì)兒它回送的數(shù)據(jù)
          3. 一個(gè)空行
          4. 實(shí)體內(nèi)容【服務(wù)器向客戶端回送的數(shù)據(jù)

          狀態(tài)行:

          • 格式: HTTP版本號(hào) 狀態(tài)碼 原因敘述
          • 狀態(tài)行:HTTP/1.1 200 OK
          • 狀態(tài)碼用于表示服務(wù)器對(duì)請(qǐng)求的處理結(jié)果,它是一個(gè)三位的十進(jìn)制數(shù)。響應(yīng)狀態(tài)碼分為5類


          首部字段例子:

          • Location: http://www.it315.org/index.jsp 【服務(wù)器告訴瀏覽器要跳轉(zhuǎn)到哪個(gè)頁(yè)面
          • Server:apache tomcat【服務(wù)器告訴瀏覽器,服務(wù)器的型號(hào)是什么】
          • Content-Encoding: gzip 【服務(wù)器告訴瀏覽器數(shù)據(jù)壓縮的格式
          • Content-Length: 80 【服務(wù)器告訴瀏覽器回送數(shù)據(jù)的長(zhǎng)度】
          • Content-Language: zh-cn 【服務(wù)器告訴瀏覽器,服務(wù)器的語(yǔ)言環(huán)境】
          • Content-Type: text/html; charset=GB2312 【服務(wù)器告訴瀏覽器,回送數(shù)據(jù)的類型
          • Last-Modified: Tue, 11 Jul 2000 18:23:51 GMT【服務(wù)器告訴瀏覽器該資源上次更新時(shí)間】
          • Refresh: 1;url=http://www.it315.org【服務(wù)器告訴瀏覽器要定時(shí)刷新
          • Content-Disposition: attachment; filename=aaa.zip【服務(wù)器告訴瀏覽器以下載方式打開(kāi)數(shù)據(jù)
          • Transfer-Encoding: chunked 【服務(wù)器告訴瀏覽器數(shù)據(jù)以分塊方式回送】
          • Set-Cookie:SS=Q0=5Lb_nQ; path=/search【服務(wù)器告訴瀏覽器要保存Cookie
          • Expires: -1【服務(wù)器告訴瀏覽器不要設(shè)置緩存
          • Cache-Control: no-cache 【服務(wù)器告訴瀏覽器不要設(shè)置緩存
          • Pragma: no-cache 【服務(wù)器告訴瀏覽器不要設(shè)置緩存
          • Connection: close/Keep-Alive 【服務(wù)器告訴瀏覽器連接方式】
          • Date: Tue, 11 Jul 2000 18:23:51 GMT【服務(wù)器告訴瀏覽器回送數(shù)據(jù)的時(shí)間】

          對(duì)于HTTP首部這一部分是非常龐大的一個(gè)章節(jié),知識(shí)點(diǎn)也很多,我就沒(méi)有一一去記錄了。用到的時(shí)候再查吧。我看的是《圖解HTTP》。

          HTTPS簡(jiǎn)述

          HTTP在安全上是不足的

          • 通信使用明文【沒(méi)有加密過(guò)內(nèi)容的】
          • 不驗(yàn)證通信方身份,無(wú)論是客戶端和服務(wù)器,都是隨意通信的
          • 無(wú)法證明報(bào)文的完整性【別人監(jiān)聽(tīng)后,可以篡改】

          我們一般在上網(wǎng)時(shí),使用抓包工具就很容易獲取到HTTP請(qǐng)求的信息了,這是TCP/IP在網(wǎng)絡(luò)通信中無(wú)法避免的。

          假設(shè)我們對(duì)HTTP報(bào)文進(jìn)行加密了, 那也僅僅是是內(nèi)容的加密。別人獲取到了HTTP內(nèi)容了,即使無(wú)法破解HTTP內(nèi)容,還是能夠篡改的。

          我們最好就是使用SSL建立安全的通信線路,就可以在這條線路上進(jìn)行HTTP通信了。

          其實(shí)HTTPS就是披著SSL的HTTP…

          HTTPS使用的是共享密鑰和公開(kāi)私有密鑰混合來(lái)進(jìn)行加密的。由于公開(kāi)私有密鑰需要太多的資源,不可能一直以公開(kāi)私有密鑰進(jìn)行通信。因此,HTTP在建立通信線路的時(shí)候使用公開(kāi)私有密鑰,當(dāng)建立完連接后,隨后就使用共享密鑰進(jìn)行加密和解密了

          對(duì)于認(rèn)證方面,HTTPS是基于第三方的認(rèn)證機(jī)構(gòu)來(lái)獲取認(rèn)受認(rèn)可的證書(shū)、因此,可以從中認(rèn)證該服務(wù)器是否是合法的。

          而客戶端方面則需要自己購(gòu)買(mǎi)認(rèn)證證書(shū)、這實(shí)施起來(lái)難度是很大的【認(rèn)證證書(shū)需要錢(qián)】。

          所以,一般的網(wǎng)站都是使用表單認(rèn)證就算了,這是用得最廣泛的客戶端認(rèn)證了。

          Java識(shí)堂,一個(gè)高原創(chuàng),高收藏,有干貨的微信公眾號(hào),一起成長(zhǎng),一起進(jìn)步,歡迎關(guān)注

          習(xí)Python也有一段時(shí)間了,在學(xué)習(xí)過(guò)程中不斷的練習(xí)學(xué)到的各類知識(shí),做的最多的還是爬蟲(chóng),也就是簡(jiǎn)單的數(shù)據(jù)采集,有采集圖片(這個(gè)最多了。。。),有下載電影的,也有學(xué)習(xí)相關(guān)的比如ppt模板的抓取,當(dāng)然也寫(xiě)過(guò)類似收發(fā)郵件,自動(dòng)登錄論壇發(fā)帖,驗(yàn)證碼相關(guān)操作等等!

          這些腳本有一個(gè)共性,都是和web相關(guān)的,總要用到獲取鏈接的一些方法,在此總結(jié)一下,也共享給正在學(xué)習(xí)的小伙伴

          安裝相關(guān)

          python的各個(gè)版本其實(shí)分別并不大,所以不用太糾結(jié)用3.6還是3.7.

          而我們經(jīng)常使用的庫(kù)呢,建議大家學(xué)到什么庫(kù)安裝什么庫(kù)

          有的同學(xué)會(huì)糾結(jié),庫(kù)安裝不上的問(wèn)題,這個(gè)推薦大家百度搜索:python whl 第一個(gè)就是吧,在里面有各個(gè)庫(kù)的各個(gè)版本,選擇對(duì)應(yīng)的下載回來(lái),用pip install 文件完整路徑 安裝即可!

          最基本的抓站——獲取源代碼

          import requests#導(dǎo)入庫(kù)

          html = requests.get(url)#獲取源代碼

          適用于靜態(tài)網(wǎng)頁(yè)

          網(wǎng)站反“反爬”

          大部分的網(wǎng)站(各類中小型網(wǎng)站)都會(huì)需要你的代碼有headers的信息,如果沒(méi)有,會(huì)直接拒絕你的訪問(wèn)!大型網(wǎng)站反而很少,尤其是門(mén)戶網(wǎng)站,比如新浪新聞、頭條圖集、百度圖片的爬蟲(chóng),基本沒(méi)有什么反爬措施,相關(guān)內(nèi)容可以看看我的其他文章!

          而有反爬措施的網(wǎng)站,大部分可以按加入U(xiǎn)A信息——加入HOST、Referer(反盜鏈)信息的順序加入到headers數(shù)據(jù)(字典格式)中來(lái)嘗試!代碼格式 requeststs.get(url,headers=headers)

          UA信息是瀏覽器信息,告訴對(duì)方服務(wù)器我們是什么瀏覽器,平時(shí)可以收集下相關(guān)信息做個(gè)UA池,需要的時(shí)候調(diào)用就可以,也可以隨機(jī)調(diào)用,防止被網(wǎng)站發(fā)現(xiàn),注意的是如果是移動(dòng)端,一定要注意移動(dòng)端的網(wǎng)頁(yè)和pc端的不一樣,比如做微博爬蟲(chóng),我們就比較喜歡移動(dòng)端,它的反爬力度比pc端的要低很多,也提醒大家,如果一個(gè)網(wǎng)站反爬很厲害,你可以去看看移動(dòng)端(手機(jī)登錄然后復(fù)制url),也許會(huì)有驚喜!

          ua信息

          HOST信息, 網(wǎng)站的主機(jī)信息,這個(gè)一般是不變的

          Referer信息 ,這個(gè)就是“反盜鏈”的關(guān)鍵信息,簡(jiǎn)單的說(shuō),就是你是從哪里到當(dāng)前頁(yè)面的,破解也很簡(jiǎn)單,把url放到里面就行!

          如果上述辦法還是繞不過(guò)反爬,那么就麻煩一些,把headers里面的信息都寫(xiě)進(jìn)去吧

          終極反“反爬”:去學(xué)習(xí)selenium吧少年!

          保存文件

          其實(shí)可以簡(jiǎn)單的分兩大類:字符串內(nèi)容保存和其他內(nèi)容保存!那么簡(jiǎn)單的2中代碼就可以解決

          a+為文末追加寫(xiě)入模式,適用于字符串內(nèi)容的寫(xiě)入,注意排版,也可以在'a+'后面添加參數(shù)encoding='utf-8'指定保存文本的編碼格式

          wb為二進(jìn)制寫(xiě)入模式,適用于找到對(duì)象的真實(shí)下載地址后用二進(jìn)制方式下載文件

          未完待續(xù)

          篇幅有限,本來(lái)想寫(xiě)完的,但是有人和我說(shuō),寫(xiě)的太多沒(méi)人看。。。這就很尷尬了!那就先寫(xiě)到這里吧!

          也正好有時(shí)間重新整理下后面的內(nèi)容,大概有:自動(dòng)登錄(cookie池)和保持登錄、ip代理、驗(yàn)證碼(這個(gè)是大項(xiàng))以及scarpy框架的一些注意事項(xiàng)。

          有其他技巧或者疑問(wèn)的同學(xué),也可以在評(píng)論區(qū)寫(xiě)上,咱們一起討論哦!


          主站蜘蛛池模板: 亚洲日韩精品国产一区二区三区| 国产在线精品一区二区在线看| 国产一区二区精品久久岳| 中文字幕日韩精品一区二区三区| 日本精品一区二区三区四区| 无码人妻av一区二区三区蜜臀| 亚洲午夜在线一区| 亚无码乱人伦一区二区| 中文字幕日韩人妻不卡一区| 99精品一区二区免费视频| 视频在线一区二区| 一区二区三区四区无限乱码 | 日本一区二区三区在线看 | 福利一区福利二区| 亚洲av日韩综合一区二区三区| 一区二区三区无码高清视频| 3D动漫精品啪啪一区二区下载| 亚洲国产精品综合一区在线 | 一区二区无码免费视频网站| 日本高清不卡一区| 波多野结衣的AV一区二区三区 | 精品国产高清自在线一区二区三区| 亚洲国产精品一区二区第一页免| 亚洲另类无码一区二区三区| 国产AV一区二区三区传媒| 亚洲国产成人久久一区久久| 国产精品一区不卡| 麻豆精品一区二区综合av| 无码人妻精品一区二区三区9厂| 国产精品香蕉在线一区| 精品一区二区三区自拍图片区| 国产在线一区二区综合免费视频| 一区二区三区在线观看视频| 无码精品人妻一区二区三区AV| 国产主播福利精品一区二区| 波多野结衣在线观看一区| 又紧又大又爽精品一区二区| AV天堂午夜精品一区| 国产精品一区二区久久不卡| 色狠狠AV一区二区三区| 国产精品亚洲午夜一区二区三区 |