亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
3.7 自定義響應頭

Spring Security 的實現機制使得它可以輕易的添加安全響應頭。3.7.1 靜態頭例如配置如下自定義頭:X-Custom-Security-Header: header-value我們可以通過 StaticHeadersWriter 對象添加:@EnableWebSecuritypublic class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.headers(headers -> headers.addHeaderWriter(new StaticHeadersWriter("X-Custom-Security-Header","header-value"))); }}3.7.2 動態添加當Spring Security 的默認配置方式不能滿足我們添加響應頭的需求時,我們可以通過 HeadersWriter 實例動態添加。例如動態添加 X-Frame-Options 頭:@EnableWebSecuritypublic class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.headers(headers -> headers.addHeaderWriter(new XFrameOptionsHeaderWriter(XFrameOptionsMode.SAMEORIGIN))); }}3.7.3 為指定請求添加響應頭有時候我們只想為某個確定的請求添加響應頭,例如只針對對登錄頁面的請求,這是可以通過 DelegatingRequestMatcherHeaderWriter 實現。例如:@EnableWebSecuritypublic class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { RequestMatcher matcher = new AntPathRequestMatcher("/login"); DelegatingRequestMatcherHeaderWriter headerWriter = new DelegatingRequestMatcherHeaderWriter(matcher,new XFrameOptionsHeaderWriter()); http.headers(headers -> headers.frameOptions(frameOptions -> frameOptions.disable()).addHeaderWriter(headerWriter)); }}

1. 請求行

我們先來看下第一部分,請求行:GET / HTTP/1.1請求行里的 GET 是請求方法。請求方法主要是告訴服務器端,客戶端要對資源實行什么樣的具體操作,方便服務器進行響應的處理。HTTP 1.0 規定的方法: GET,POST,HEAD;HTTP 1.1 新增的請求方法:OPTIONS,PUT,DELETE,TRACE,CONNECT;HTTP 規定的主要請求如下表所示,我們主要使用的實際上就是 get,post 這兩個請求。常用的請求方法序號請求方法方法描述1GET用來獲取服務器的信息。2POST用于創建一個文件,請求是非冪等的。3HEAD通過這個來獲取響應的報頭文件,不包含的具體內容。4PUT主要是用來更新文件,這個方法對服務器來講,應該是冪等的。5DELETE這個命令是用來請求讓服務器端來刪除特定的信息。6OPTIONS這個方法可以讓客戶端可以查看服務器可以提供的請求方法等信息。7TRACE這個主要用于測試和診斷,可以回顯服務器的信息。8CONNECTHTTP/1.1協議中預留的請求方法,不常使用。Get 后面的 / 是來標明請求的資源信息,我們這里是想訪問慕課網的主頁,所以寫 /。 HTTP/1.1 指的是 HTTP 的協議版本。Tips:HTTP 是在 1990 左右提出的協議,距今已經有幾十年的歷史了。廣泛使用的版本有 1.0,1.1,現在也有 2.0 的版本,不過還沒有普及。除此之外,對安全要求高的一些網站,也有的開始采用 HTTPS 協議進行傳輸。HTTPS 提供了更多的安全校驗,是利用 SSL/TLS 技術進行加密的,相對于普通的 HTTP,更加安全,隱私更不容易泄露。好了說完了請求行,讓我們來介紹一下請求頭部。

401 Unauthorized

請求沒有權限,通常返回的響應頭部會包含 WWW-Authenticate 的頭,瀏覽器遇到這種響應一般會彈出一個對話框,讓用戶重新提交用戶名和密碼進行認證。服務端響應HTTP/1.1 401 UnauthorizedWWW-Authenticate: Basic; realm="Secured area"客戶端重新提交認證GET / HTTP/1.1Authorization: Basic j3VsbCBkb25lOnlvdhBmb3Vu89B0aGUgZWFzdGVyIoUnZwo=

Nginx 配置初步(上)

本節的目標是了解 Nginx 的基本配置。關于 Nginx 的配置,主要是以下 5 個方面:初始配置基本語法http 服務配置tcp/udp反向代理每個部分其實有比較多的擴展內容,今天我們會講解初始配置以及配置文件的基本語法,后續的 http 服務配置、tcp/udp 配置和反向代理配置會在下一節中介紹。

2.3 第三步:使用 Swagger Editor 生成 Swagger-UI 界面

在配置好 Swagger Editor 基本配置信息和 Swagger Editor 接口配置信息之后,我們就可以在項目中生成 Swagger-UI 界面了。我們生成 Swagger-UI 界面需要依賴 http-server ,我們在編輯器的控制臺中輸入以下命令即可: http-server swagger-editor .yml文件路徑即我們為 Swagger Editor 指定需要使用的 .yml 配置源文件即可,生成后的界面如下圖所示。

5. 小結

本節內容介紹了 Http 請求 11 個階段中的最后幾個,分別是 try_files 階段、content 階段和 log 階段,同時還有對應階段中生效的指令。這些在配置靜態資源訪問時非常有用,因為主要是涉及到讀取靜態資源的內容。最后的 log 模塊也是非常重要的一步,良好的日志記錄有助于我們后續排查問題以及分析系統性能瓶頸。今天 Http 請求的 11 個處理階段正式講完,后面還需要多多深入每個階段的指令學習和實驗,徹底掌握 Nginx 的 Http 模塊。

4.1. Netty 主啟動類

public class TestServer { public static void main(String[] args) throws Exception { EventLoopGroup bossGroup = new NioEventLoopGroup(1); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap serverBootstrap = new ServerBootstrap(); serverBootstrap .group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer<NioSocketChannel>() { protected void initChannel(NioSocketChannel ch) { ChannelPipeline pipeline = ch.pipeline(); //1.Netty提供的針對Http的編解碼 pipeline.addLast(new HttpServerCodec()); //2.自定義處理Http的業務Handler pipeline.addLast(new TestHttpServerHandler()); } }); ChannelFuture channelFuture = serverBootstrap.bind(8080).sync(); channelFuture.channel().closeFuture().sync(); } finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } }}代碼說明:這個是 Netty 的基本模板類,跟我們之前寫的并沒有什么不同,只是它給我們提了一個特殊的類 HttpServerCodec,從字面上都能猜到它就是針對 Http 服務的編解碼器。

1.2 limit_req 模塊

ngx_http_limit_req_module 模塊主要用于處理突發流量,它基于漏斗算法將突發的流量限定為恒定的流量。如果請求容量沒有超出設定的極限,后續的突發請求的響應會變慢,而對于超過容量的請求,則會立即返回 503(默認)錯誤。該模塊模塊中比較重要的指令有:limit_req_zone 指令,定義共享內存, key 關鍵字以及限制速率Syntax: limit_req_zone key zone=name:size rate=rate [sync];Default: —Context: httplimit_req 指令,限制并發連接數Syntax: limit_req zone=name [burst=number] [nodelay | delay=number];Default: —Context: http, server, locationlimit_req_log_level 指令,設置服務拒絕請求發生時打印的日志級別Syntax: limit_req_log_level info | notice | warn | error;Default:limit_req_log_level error;Context: http, server, locationlimit_req_status 指令, 設置服務拒絕請求發生時返回狀態碼Syntax: limit_req_status code;Default: limit_req_status 503;Context: http, server, location

1. 什么是 REST

REST 全稱是 Representational State Transfer 的縮寫,中文翻譯是表述性狀態轉移。Roy Thomas Fielding 首次在他的博士論文中提出的 REST 這個概念,他把互聯網軟件的架構原則,定名為 REST。Roy Thomas Fielding 提出 REST 的概念,是為了得到一個以網絡為基礎的應用軟件的架構,得到一個功能強、性能好、適宜通信的架構。REST 指的是一組架構約束條件和原則,如果一個架構符合 REST 的約束條件和原則,我們就稱它為 RESTful 架構。雖然 REST 本身受 Web 技術的影響很深,但理論上,REST 架構風格并不是綁定在 HTTP 應用上。目前 HTTP 是唯一與 REST 相關的應用領域,因此 REST 通常是指基于 HTTP 實現的 REST。

3.3 路徑參數的使用

很多時候我們的路徑是包含參數信息的,而規則的應用往往也和參數信息想匹配。例如針對用戶信息的 RESTful 資源地址 /user/{userId}。我們可以在表達式中使用這些參數。例如,假設我們的擴展表達式方法如下:public class WebSecurity { public boolean checkUserId(Authentication authentication, int id) { ... }}此方法的 id 參數需要傳入路徑中的 userId 的值,那我們在配置表達式時可用如下方式:<http> <intercept-url pattern="/user/{userId}/**" access="@webSecurity.checkUserId(authentication,#userId)"/> ...</http>或者用 Java 的方式配置http .authorizeRequests(authorize -> authorize .antMatchers("/user/{userId}/**").access("@webSecurity.checkUserId(authentication,#userId)") ... );上述寫法的結果都是將 userId 作為參數傳入了方法之中,加入用戶訪問的 URL 地址為 /user/123/resource,則傳入的 id 參數為 123。

2.4 前端應用部署

前端應用的部署更加簡單,我們直接在云服務器上下載 nginx 然后解壓。打開網址 http://nginx.org/en/download.html ,點擊下圖中的鏈接下載即可。nginx 下載鏈接下載解壓后,將前端頁面直接放到 nginx/html 目錄下即可。當然如果有很多網頁,可以先在該目錄下建立子目錄便于歸類網頁。我們建立 shop-front 目錄(表示商城系統的前端項目),然后將網頁放入其中,效果如下:商城系統前端項目目錄內容注意還需要修改 goods.html 中訪問的后端 URL 地址,假設云服務器的公網 IP 為 x.x.x.x ,則修改為:實例:$.ajax({ type: "GET", url: "http://x.x.x.x:8080/goods", //后端接口地址 dataType: "json", contentType: "application/json; charset=utf-8", success: function (res) { $.each(res, function (i, v) { row = "<tr>"; row += "<td>" + v.id + "</td>"; row += "<td>" + v.name + "</td>"; row += "<td>" + v.price + "</td>"; row += "<td>" + v.pic + "</td>"; row += "</tr>"; $("#goodsTable").append(row); }); }, error: function (err) { console.log(err); } });此處解釋下后端地址 http://x.x.x.x:8080/goods , HTTP 代表協議, x.x.x.x 代表云服務器公網地址, 8080 是我們后端項目的啟動端口,由于我們沒有在配置文件中設置,所以默認就是 8080 ,最后 goods 是控制器中設定的后端接口路徑。雙擊 nginx.exe 啟動 nginx ,由于 nginx 默認啟動端口是 80 ,所以此時訪問 http://x.x.x.x ,效果如下,說明 nginx 啟動成功!nginx 已啟動成功

1. 簡介

通用的首部字段指的是請求和響應的首部都能使用的字段。請求示例GET / HTTP/1.1Host: www.xianlaiwan.cnConnection: keep-alive請求實體內容響應示例HTTP/1.1 200 OKDate: Web 29 Apr 2020 08:08:08 GMTConnection: keep-alive響應實體內容示例中請求和響應的協議首部均有 Connection 字段,這類即為公共首部字段。

4.1 自定義 Token 倉庫

默認情況下,CSRF Token 存儲在 HttpSession 中,使用 HttpSessionCsrfTokenRepository 對象維護。如果需要進行擴展,比如不僅要在 HTTP 請求中攜帶 Token,也需要在 JS 應用中應用 Token,那需要通過如下方式:在配置類中構造并注入 CookieCsrfTokenRepository 對象。@EnableWebSecuritypublic class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) { http.csrf(csrf -> csrf.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())); }}

1. Nginx 的四層反向代理

前面我們剛開始使用 Nginx 時只是用了 http 指令塊,因為是針對 http 請求進行處理。這進行的是四層反向代理,轉發 TCP 或者 UDP 協議的報文。針對該層的處理,Nginx 是使用了 stream 模塊進行處理,對應的是 stream 指令塊,它和 http 指令塊非類似,用法幾乎一致。stream 指令塊里面可以包含 server 指令塊,server 指令塊里面也可以包含 listen 指令塊指定監聽的端口、還可以包含 proxy_pass指令,對該端口監聽的 tcp 或者 udp 報文進行轉發??傊?,和 http 指令塊大部分用法一致。...stream { ... server { listen 3440; # 轉發四層流量 proxy_pass 192.168.1.103:3440; } ...}...此外,從nginx-1.11.2版開始, ngx_stream_core_module,也同 http 模塊一樣支持變量,部分支持變量如下,這和 http 模塊也是類似的,甚至連變量名都非常相似:$binary_remote_addr: 二進制格式的客戶端地址$bytes_received: 從客戶端接收到的字節數$bytes_sent: 發往客戶端的字節數$hostname: 連接域名$msec: 毫秒精度的當前時間$nginx_version: nginx的版本$pid: worker進程號$protocol: 通信協議(UDP or TCP)$remote_addr: 客戶端ip$remote_port: 客戶端端口$server_addr: 接受連接的服務器ip,計算此變量需要一次系統調用。所以避免系統調用,在listen指令里必須指定具體的服務器地址并且使用參數bind。$server_port: 接受連接的服務器端口$session_time: 毫秒精度的會話時間(版本1.11.4開始)$status: 會話狀態(版本1.11.4開始), 可以是一下幾個值:200成功400不能正常解析客戶端數據403禁止訪問500服務器內部錯誤502網關錯誤,比如上游服務器無法連接503服務不可用,比如由于限制連接等措施導致$time_iso8601: ISO 8601時間格式$time_local: 普通日志格式的時間戳

2.1 限制某些 ip 地址的訪問權限

在 access 階段,我們可以通 allow 和 deny 指令來允許和拒絕某些 ip 的訪問權限,指令的用法如下:Syntax: allow address | CIDR | unix: | all;Default: —Context: http, server, location, limit_exceptSyntax: deny address | CIDR | unix: | all;Default: —Context: http, server, location, limit_except實例allow 和 deny 指令后面可以跟具體 ip 地址,也可以跟一個 ip 段, 或者所有(all)。location / { deny 192.168.1.1; allow 192.168.1.0/24; allow 10.1.1.0/16; allow 2001:0db8::/32; deny all;}

5. 小結

本節講述了如何在 Android 中發起 http 請求,HttpURLConnection 的使用方式非常簡單,但是需要你對 http 協議本身有一定的了解,作為開發者這個是必備的知識點。當然對于大型項目而言,需要涉及到 DNS、緩存、安全校驗等等高級操作,這時候 HttpURLConnection 會顯得有點輸出乏力,這就需要第三方的框架出場了,萬變不離其宗,所有的框架到了底層其實都是一樣的基本原理,所以還是希望大家能夠熟悉 http 協議,并掌握 HttpURLConnection 的用法。

3. 修改項目啟動配置

我們運行啟動類,啟動 spring-boot-profile 應用,控制臺會發現如下提示:Tomcat started on port(s): 8080 (http) with context path ''可以看出, Spring Boot 應用默認啟動端口是 8080 ,默認項目路徑是空。我們可以通過修改 resources/application.properties 來自定義項目啟動配置:實例:# 啟動端口server.port=8000# 項目路徑server.servlet.context-path=/spring-boot-profile再次啟動應用,控制臺提示變為:Tomcat started on port(s): 8000 (http) with context path '/spring-boot-profile'此時項目對應的訪問路徑為: http://127.0.0.1:8000/spring-boot-profile , 使用瀏覽器訪問效果如下:瀏覽器顯示返回數據

3.3 <a href="http://object.is/">Object.is</a>()

Object.is() 被稱為同值相等的比較,在兩個值進行比較時用到了很多規則,比如上面 === 在判斷帶符號的 0 時返回的都是 true,NaN 和任何值都不相等,但 Object.is() 給出了截然相反的結果:Object.is(0, -0); // falseObject.is(NaN, NaN); // true下面我們來看下,Object.is() 都有哪些規則:當操作值都沒有被定義時,這時它們的值是 undefined ,通過 Object.is() 判斷的結果為 true。let alet bObject.is(a,b) // trueObject.is() 也是嚴格區分大小寫的。Object.is('Imooc', 'Imooc') // trueObject.is('Imooc', 'imooc') // false操作值的類型必須相同,無論是什么值,只要類型不一樣就會返回 false。Object.is(null, 'null') // falseObject.is(undefined, 'undefined') // false判斷引用類型的值時,引用類型的地址相同時,則相等,與 == 和 === 判斷的結果是一樣的。let a = {"name": "imooc"}let b = aObject.is(a, b) // trueObject.is({"name": "imooc"}, {"name": "imooc"}) // falseObject.is(window, window) // true, 只有一個window全局變量操作數是 0、+0、-0 的比較,0 和 +0 是相等的,因為正號可以省略,但是 0 和 -0 是不相等的,這樣就和 === 判斷的結果不一樣了。Object.is(0, +0) // trueObject.is(0, -0) // false當兩個操作值是 NaN 時,使用 Object.is() 返回的結果是 true 這個和 === 返回的結果不一樣,如果計算的結果是 NaN 的話,返回的結果也是 true。Object.is(NaN, NaN) // trueObject.is(NaN, 0/0) // true

4.1 expires 指令用法

首先準備 nginx.conf,中間簡單配置幾條 expires 指令用作測試:...http{ server { listen 8000; location / { default_type text/plain; expires 10m; #expires -1h; return 200 '8000, server\n'; } }}...下面觀察請求結果:# 使用 expires 10m 配置,可以看到Expires值正好為10分鐘后[shen@shen ~]$ curl http://180.76.152.113:8000 -IHTTP/1.1 200 OKServer: nginx/1.17.6Date: Thu, 06 Feb 2020 11:37:17 GMTContent-Type: text/plainContent-Length: 13Connection: keep-aliveExpires: Thu, 06 Feb 2020 11:47:17 GMTCache-Control: max-age=600# 使用 expires -1h 配置, -1h表示環境一個小時前過期了,所以返回Cache-Control的值為no-cache[shen@shen ~]$ curl http://180.76.152.113:8000 -IHTTP/1.1 200 OKServer: nginx/1.17.6Date: Thu, 06 Feb 2020 11:37:32 GMTContent-Type: text/plainContent-Length: 13Connection: keep-aliveExpires: Thu, 06 Feb 2020 10:37:32 GMTCache-Control: no-cache

2. 安全響應頭

Spring Security 提供了一些默認 HTTP 安全性相關的響應頭。這些默認響應頭如下:

3.4 啟動應用

訪問 http://127.0.0.1:8080/goods ,返回內容如下,可見后端接口已經可用。瀏覽器顯示返回數據

3. 入口 <a href="http://main.py">main.py</a>

創建文件 main.py,它是 Flask 程序的入口,源代碼由如下部分構成:

4.2 禁用 CSRF 保護

默認情況下,CSRF 保護功能已被開啟,如果需要關閉,可通過如下方式配置:@Configuration@EnableWebSecuritypublic class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) { http.csrf(csrf -> csrf.disable()); }}

3. Nginx中的壓縮配置

Nginx 的壓縮配置主要是用在與瀏覽交互中,對網頁、css、js等靜態資源進行壓縮,通過消耗 cpu 的計算資源來節約大量的帶寬,提高傳輸效率,給用戶良好的體驗。Nginx 中的 ngx_http_gzip_module 就是專門處理這里壓縮功能的模塊。其中部分重要指如下:gzip: 是否打開 gzip 壓縮功能;Syntax: gzip on | off;Default: gzip off;Context: http, server, location, if in locationgzip_buffers: 設置壓縮所需要的緩沖區大小;Syntax: gzip_buffers number size;Default: gzip_buffers 32 4k|16 8k;Context: http, server, locationgzip_comp_level: 設置壓縮級別,從1-9;越大壓縮率越高,同時消耗cpu資源也越多;Syntax: gzip_comp_level level;Default: gzip_comp_level 1;Context: http, server, locationgzip_types:需要壓縮的文件格式 text/html默認會壓縮,不用添加;Syntax: gzip_types mime-type ...;Default: gzip_types text/html;Context: http, server, locationgzip_min_length: 壓縮文件最小大小;Syntax: gzip_min_length length;Default: gzip_min_length 20;Context: http, server, location一個常見的壓縮配置如下: # 開啟gzip壓縮 gzip on; # http的協議版本 gzip_http_version 1.0; # IE版本1-6不支持gzip壓縮,關閉 gzip_disable 'MSIE[1-6].'; #需要壓縮的文件格式 gzip_types text/css text/javascript application/javascript image/jpeg image/png image/gif; #設置為4個8K內存作為壓縮結果流緩存 gzip_buffers 4 8k; #壓縮文件最小大小 gzip_min_length 1k; #壓縮級別1-9 gzip_comp_level 9; #給響應頭加個vary,告知客戶端能否緩存 gzip_vary on; #反向代理時使用 gzip_proxied off;注意: gzip 的開啟需適應特定的場景,比如大文件和圖片的傳輸就不是和開啟 gzip 功能,壓縮效果不明顯的同時還白白耗費系統的資源,所以使用時需要慎重考慮。

3.3 測試 HTTP 基礎認證

使用 httpBasic 測試基本認證:mvc.perform(get("/").with(httpBasic("user","password")))這一步相當于為請求增加了以下認證頭:Authorization: Basic dXNlcjpwYXNzd29yZA==

1.3 簡單

指的是 HTTP 報文設計的簡單易懂,對新手很友好,很容易上手,降低了學習門檻。

1. 下載源碼包并解壓

打開終端并運行下面兩條命令即可下載并解壓 Nginx :$ wget http://Nginx.org/download/nginx-1.17.6.tar.gz$ tar -xzf Nginx-1.17.6.tar.gz

HTTP 協議狀態碼-3XX

3XX 代表重定向,代表需要客戶端采取進一步的操作才能完成請求。通常,這些狀態碼用來重定向,后續的請求地址(重定向目標)在本次響應的 Location 域中指明。

2.4 服務器端解析請求

當一個 HTTP 請求打進服務器之后,一般的流程是:網關層(例如Ngnix)最先獲取請求,然后路由轉發到具體的Web服務,經過一段業務邏輯之后,可能還會查詢數據庫,最后將處理的結果返回給瀏覽器客戶端。對于后端開發程序員來說,日常的工作就集中在服務器端,特別是流程圖中的"Web業務服務"這塊,例如基于 Spring 框架、Django 框架或者ThinkPHP 框架進行業務邏輯開發和上線。(HTTP 請求進入服務器端后的解析流程圖)

直播
查看課程詳情
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號