61396-Go語(yǔ)言程序設(shè)計(jì)項(xiàng)目化教程(微課版)7.3 中間件_第1頁(yè)
61396-Go語(yǔ)言程序設(shè)計(jì)項(xiàng)目化教程(微課版)7.3 中間件_第2頁(yè)
61396-Go語(yǔ)言程序設(shè)計(jì)項(xiàng)目化教程(微課版)7.3 中間件_第3頁(yè)
61396-Go語(yǔ)言程序設(shè)計(jì)項(xiàng)目化教程(微課版)7.3 中間件_第4頁(yè)
61396-Go語(yǔ)言程序設(shè)計(jì)項(xiàng)目化教程(微課版)7.3 中間件_第5頁(yè)
已閱讀5頁(yè),還剩24頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

中間件Gin中間件會(huì)話控制中間件開發(fā)流程01.03.02.目錄文件上傳04.01Gin中間件中間件定義Gin默認(rèn)中間件中間件的分類1Gin中間件中間件是介于應(yīng)用系統(tǒng)和系統(tǒng)軟件之間的一類軟件,它使用系統(tǒng)軟件所提供的基礎(chǔ)服務(wù)(功能),銜接網(wǎng)絡(luò)上應(yīng)用系統(tǒng)的各個(gè)部分或不同的應(yīng)用,能夠達(dá)到資源共享、功能共享的目的。中間件的定義Gin框架允許開發(fā)者在處理請(qǐng)求的過程中,加入用戶自己的函數(shù),這個(gè)函數(shù)就叫中間件。中間件適合處理一些公共的業(yè)務(wù)邏輯,比如登錄認(rèn)證、權(quán)限校驗(yàn)、數(shù)據(jù)分頁(yè)、記錄日志、耗時(shí)統(tǒng)計(jì)等。例如我們可以設(shè)置當(dāng)用戶訪問一個(gè)網(wǎng)頁(yè)的時(shí)候,不管訪問什么路徑都需要先進(jìn)行登錄,這就需要為所有路徑的處理函數(shù)設(shè)置統(tǒng)一的一個(gè)中間件,Gin的中間件必須是一個(gè)gin.HandlerFunc類型。Gin中的中間件1Gin中間件Gin框架本身提供了一些基礎(chǔ)的中間件,使用router:=gin.Default()定義route時(shí),是構(gòu)建一個(gè)自帶默認(rèn)中間件的*Engine,該中間件默認(rèn)帶了Logger()和Recovery()。Gin默認(rèn)中間件//DefaultreturnsanEngineinstancewiththeLoggerandRecoverymiddlewarealreadyattached.funcDefault()*Engine{ debugPrintWARNINGDefault() engine:=New() engine.Use(Logger(),Recovery()) returnengine}//Useattachesaglobalmiddlewaretotherouter.i.e.themiddlewareattachedthroughUse()willbeincludedinthehandlerschainforeverysinglerequest.Even404,405,staticfiles...//Forexample,thisistherightplaceforaloggerorerrormanagementmiddleware.func(engine*Engine)Use(middleware...HandlerFunc)IRoutes{ engine.RouterGroup.Use(middleware...) engine.rebuild404Handlers() engine.rebuild405Handlers() returnengine}//LoggerinstancesaLoggermiddlewarethatwillwritethelogstogin.DefaultWriter.//Bydefault,gin.DefaultWriter=os.Stdout.funcLogger()HandlerFunc{ returnLoggerWithConfig(LoggerConfig{})}//Recoveryreturnsamiddlewarethatrecoversfromanypanicsandwritesa500iftherewasone.funcRecovery()HandlerFunc{ returnRecoveryWithWriter(DefaultErrorWriter)}1Gin中間件Gin的中間件是通過Use方法設(shè)置的,它接收一個(gè)可變參數(shù),所以我們同時(shí)可以設(shè)置多個(gè)中間件。Default函數(shù)會(huì)默認(rèn)綁定兩個(gè)已經(jīng)準(zhǔn)備好的中間件,它們就是Logger和Recovery,幫助我們打印日志輸出和painc處理。1Gin中間件HTTPBasicAuthorization是HTTP常用的認(rèn)證方案,它通過Authorization請(qǐng)求消息頭含有服務(wù)器用于驗(yàn)證用戶代理身份的憑證。格式為:Authorization:Basic<credentials>如果認(rèn)證不成功,服務(wù)器返回401Unauthorized狀態(tài)碼以及WWW-Authenticate消息頭,讓客戶端輸入用戶名和密碼進(jìn)一步認(rèn)證。在Gin中,為我們提供了gin.BasicAuth()幫我們生成基本認(rèn)證的中間件。//BasicAuthreturnsaBasicHTTPAuthorizationmiddleware.Ittakesasargumentamap[string]stringwherethekeyistheusernameandthevalueisthepassword.funcBasicAuth(accountsAccounts)HandlerFunc{ returnBasicAuthForRealm(accounts,"")}中間件的典型應(yīng)用:HTTPBasicAuthorizationpackagemainimport( "/gin-gonic/gin")funcmain(){ r:=gin.Default() r.Use(gin.BasicAuth(gin.Accounts{ "admin":"123456", })) r.GET("/",func(c*gin.Context){ c.JSON(200,"登陸成功!") }) r.Run(":8080")}1Gin中間件1Gin中間件雖然可以使用BasicAuth()中間件做一些簡(jiǎn)單的用戶權(quán)限的認(rèn)證但當(dāng)使用了自定義的session時(shí),Gin自帶的中間件則不能滿足需求此時(shí)可以編寫自定義的中間件,并且將自定義的中間件加入到全局中間件隊(duì)列中去每一個(gè)route的請(qǐng)求同樣會(huì)到自定義的中間件中去,實(shí)現(xiàn)自定義的認(rèn)證等因此,Gin的中間件大致可以分為兩類:全局中間件和路由中間件中間件的分類全局中間件作用于所有的路由上,所有的路由請(qǐng)求都需要經(jīng)過這些全局中間件。全局中間件局部中間件作用于單個(gè)路由,并不是所有路由路由中間件02中間件開發(fā)流程N(yùn)ext()Abort()Set()Get()2中間件開發(fā)流程N(yùn)ext()將請(qǐng)求傳遞給請(qǐng)求鏈中下一個(gè)處理方法當(dāng)執(zhí)行Next()的時(shí)候,程序會(huì)掛起當(dāng)前執(zhí)行的操作,并繼續(xù)向下執(zhí)行,等執(zhí)行完成下面的函數(shù),最后再反過來執(zhí)行該中間件,完成完整請(qǐng)求的執(zhí)行Next()//Nextshouldbeusedonlyinsidemiddleware.//Itexecutesthependinghandlersinthechaininsidethecallinghandler.//SeeexampleinGitHub.func(c*Context)Next(){ c.index++ forc.index<int8(len(c.handlers)){ c.handlers[c.index](c) c.index++ }}packagemainimport( "fmt" "/gin-gonic/gin" "time")funcmain(){ r:=gin.New() r.Use(costTime()) r.GET("/",func(c*gin.Context){ c.JSON(200,"首頁(yè)") }) r.Run(":8080")}funccostTime()gin.HandlerFunc{ returnfunc(c*gin.Context){ //請(qǐng)求前獲取當(dāng)前時(shí)間

nowTime:=time.Now() //請(qǐng)求處理

c.Next() //處理后獲取消耗時(shí)間

costTime:=time.Since(nowTime) url:=c.Request.URL.String() fmt.Printf("therequestURL%scost%v\n",url,costTime) }}2中間件開發(fā)流程2中間件開發(fā)流程Abort()處理出現(xiàn)錯(cuò)誤時(shí),阻止當(dāng)前中間件之后的所有程序執(zhí)行,與return區(qū)別是Abort會(huì)繼續(xù)執(zhí)行當(dāng)前中間件,return會(huì)返回上一級(jí),不會(huì)執(zhí)行當(dāng)前中間件后的邏輯。Abort()//Abortpreventspendinghandlersfrombeingcalled.Notethatthiswillnotstopthecurrenthandler.//Let'ssayyouhaveanauthorizationmiddlewarethatvalidatesthatthecurrentrequestisauthorized.//Iftheauthorizationfails(ex:thepassworddoesnotmatch),callAborttoensuretheremaininghandlers//forthisrequestarenotcalled.func(c*Context)Abort(){ c.index=abortIndex}packagemainimport( "fmt" "/gin-gonic/gin" "time")funcmain(){ r:=gin.New() r.Use(costTime()) r.GET("/",func(c*gin.Context){ c.JSON(200,"首頁(yè)") }) r.Run(":8080")}funccostTime()gin.HandlerFunc{ returnfunc(c*gin.Context){ //請(qǐng)求前獲取當(dāng)前時(shí)間

nowTime:=time.Now() //請(qǐng)求處理

c.Abort() //處理后獲取消耗時(shí)間

costTime:=time.Since(nowTime) url:=c.Request.URL.String() fmt.Printf("therequestURL%scost%v\n",url,costTime) }}2中間件開發(fā)流程2中間件開發(fā)流程c.Set()與c.Get()用于在中間件和最終的業(yè)務(wù)處理方法中傳遞數(shù)據(jù),在認(rèn)證中間件中獲取當(dāng)前請(qǐng)求的相關(guān)信息,通過c.Set()存入,后續(xù)處理業(yè)務(wù)邏輯的函數(shù)中通過c.Get()來獲取當(dāng)前請(qǐng)求信息。Get()與Set()//Setisusedtostoreanewkey/valuepairexclusivelyforthiscontext.Italsolazyinitializesc.Keysifitwasnotusedpreviously.func(c*Context)Set(keystring,valueany){ c.mu.Lock() ifc.Keys==nil{ c.Keys=make(map[string]any) } c.Keys[key]=value c.mu.Unlock()}//Getreturnsthevalueforthegivenkey,ie:(value,true).Ifthevaluedoesnotexistitreturns(nil,false)func(c*Context)Get(keystring)(valueany,existsbool){ c.mu.RLock() value,exists=c.Keys[key] c.mu.RUnlock() return}packagemainimport( "fmt" "/gin-gonic/gin")funcmain(){ r:=gin.New() r.Use(m1,m2)//全局注冊(cè)中間件函數(shù)

r.GET("/") r.Run(":8080")}funcm1(c*gin.Context){ fmt.Println("m1in...") c.Set("name","Gin") c.Next() fmt.Println("m2out...")}funcm2(c*gin.Context){ fmt.Println("m2in...") name,_:=c.Get("name") fmt.Println(name) c.Next() fmt.Println("m2out...")}2中間件開發(fā)流程03會(huì)話控制CookieSession3會(huì)話控制是服務(wù)器保存在瀏覽器上的一段信息瀏覽器有了Cookie,向服務(wù)器發(fā)送請(qǐng)求時(shí)都會(huì)同時(shí)將Cookie發(fā)送給服務(wù)器,服務(wù)器收到請(qǐng)求后,可以根據(jù)該信息處理請(qǐng)求Cookie由服務(wù)器創(chuàng)建,并發(fā)送給瀏覽器,最終由瀏覽器保存Cookie是服務(wù)器保存在瀏覽器上的一段信息瀏覽器有了Cookie,向服務(wù)器發(fā)送請(qǐng)求時(shí)都會(huì)同時(shí)將Cookie發(fā)送給服務(wù)器,服務(wù)器收到請(qǐng)求后,可以根據(jù)該信息處理請(qǐng)求Cookie由服務(wù)器創(chuàng)建,并發(fā)送給瀏覽器,最終由瀏覽器保存Cookie參數(shù)設(shè)置//SetCookieaddsaSet-CookieheadertotheResponseWriter'sheaders.//TheprovidedcookiemusthaveavalidName.Invalidcookiesmaybe//silentlydropped.func(c*Context)SetCookie(name,valuestring,maxAgeint,path,domainstring,secure,httpOnlybool){ ifpath==""{ path="/" } http.SetCookie(c.Writer,&http.Cookie{ Name:name, Value:url.QueryEscape(value), MaxAge:maxAge, Path:path, Domain:domain, SameSite:c.sameSite, Secure:secure, HttpOnly:httpOnly, })}name、value為cookie會(huì)話的key/value值maxAge表示過期時(shí)間path表示Cookie路徑domain表示作用域secure為true時(shí)Cookie只在HTTPS中生效httpOnly防止程序受到XSS攻擊。3會(huì)話控制c.SetCookie()3會(huì)話控制//Cookiereturnsthenamedcookieprovidedintherequestor//ErrNoCookieifnotfound.Andreturnthenamedcookieisunescaped.//Ifmultiplecookiesmatchthegivenname,onlyonecookiewillbereturned.func(c*Context)Cookie(namestring)(string,error){ cookie,err:=c.Request.Cookie(name) iferr!=nil{ return"",err } val,_:=url.QueryUnescape(cookie.Value) returnval,nil}c.Cookie(key)通過鍵使用cookie()獲取值3會(huì)話控制Cookie存在不安全明文、有上限存儲(chǔ)、帶寬消耗等各種問題HTTP協(xié)議無狀態(tài),服務(wù)器不能記錄瀏覽器的訪問狀態(tài)確定不同時(shí)刻的請(qǐng)求是否來自同一個(gè)客戶端而Session對(duì)象可以存儲(chǔ)特定用戶會(huì)話所需的屬性及配置信息當(dāng)用戶在應(yīng)用程序的Web頁(yè)之間跳轉(zhuǎn)時(shí),存儲(chǔ)在Session對(duì)象中的變量將不會(huì)丟失,而是在整個(gè)用戶會(huì)話中一直存在下去當(dāng)用戶請(qǐng)求來自應(yīng)用程序的Web頁(yè)時(shí),如果該用戶還沒有會(huì)話,則Web服務(wù)器將自動(dòng)創(chuàng)建一個(gè)Session對(duì)象當(dāng)會(huì)話過期或被放棄后,服務(wù)器將終止該會(huì)話。Session對(duì)象最常見的一個(gè)用法就是存儲(chǔ)用戶的首選項(xiàng)Session依賴于Cookie,并且需要?jiǎng)?chuàng)建存儲(chǔ)引擎,設(shè)置密鑰Session3會(huì)話控制Session參數(shù)設(shè)置session:=sessions.Default(c)session.Set(key,value)session.Save()Session參數(shù)獲取session:=sessions.Default(c)session.Get(key)//shortcuttogetsessionfuncDefault(c*gin.Context)Session{ returnc.MustGet(DefaultKey).(Session)}3會(huì)話控制packagemainimport( //導(dǎo)入session包

"/gin-contrib/sessions" //導(dǎo)入session存儲(chǔ)引擎

"/gin-contrib/sessions/cookie" //導(dǎo)入gin框架包

"/gin-gonic/gin")funcmain(){ r:=gin.Default() //創(chuàng)建基于cookie的存儲(chǔ)引擎,123456789參數(shù)是用于加密的密鑰

store:=cookie.NewStore([]byte("123456789")) //設(shè)置session中間件,參數(shù)mysession,指的是session的名字,也是cookie的名字

//store是前面創(chuàng)建的存儲(chǔ)引擎,我們可以替換成其他存儲(chǔ)引擎

r.Use(sessions.Sessions("mysession",store))3會(huì)話控制 r.GET("/hello",func(c*gin.Context){ //初始化session對(duì)象

session:=sessions.Default(c) //通過session.Get讀取session值

/*session是鍵值對(duì)格式數(shù)據(jù),

因此需要通過key查詢數(shù)據(jù)*/

ifsession.Get("hello")!="world"{ //設(shè)置session數(shù)據(jù)

session.Set("hello","world") //刪除session數(shù)據(jù)

session.Delete("1234") //保存session數(shù)據(jù)

session.Save() //刪除整個(gè)session //session.Clear() } c.JSON(200,gin.H{"hello":session.Get("hello")}) }) r.Run(":8080")}04文件上傳MaxMultipartMemoryFormFile()SaveUploadedFile()MultipartForm()4文件上傳用于限制上傳文件的大小MaxMultipartMemoryFormFile()FormFile()用于獲取上傳文件的基本信息SaveUploadedFile()SaveUploadedFile()用于實(shí)現(xiàn)文件的保存MultipartForm()該方法實(shí)現(xiàn)對(duì)multiForm的解析,并可以獲得文件類型的數(shù)組,然后遍歷文件并調(diào)用SaveUploadFile保存文件<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0">

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論