版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
中間件Gin中間件會話控制中間件開發(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)的各個部分或不同的應(yīng)用,能夠達(dá)到資源共享、功能共享的目的。中間件的定義Gin框架允許開發(fā)者在處理請求的過程中,加入用戶自己的函數(shù),這個函數(shù)就叫中間件。中間件適合處理一些公共的業(yè)務(wù)邏輯,比如登錄認(rèn)證、權(quán)限校驗、數(shù)據(jù)分頁、記錄日志、耗時統(tǒng)計等。例如我們可以設(shè)置當(dāng)用戶訪問一個網(wǎng)頁的時候,不管訪問什么路徑都需要先進(jìn)行登錄,這就需要為所有路徑的處理函數(shù)設(shè)置統(tǒng)一的一個中間件,Gin的中間件必須是一個gin.HandlerFunc類型。Gin中的中間件1Gin中間件Gin框架本身提供了一些基礎(chǔ)的中間件,使用router:=gin.Default()定義route時,是構(gòu)建一個自帶默認(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è)置的,它接收一個可變參數(shù),所以我們同時可以設(shè)置多個中間件。Default函數(shù)會默認(rèn)綁定兩個已經(jīng)準(zhǔn)備好的中間件,它們就是Logger和Recovery,幫助我們打印日志輸出和painc處理。1Gin中間件HTTPBasicAuthorization是HTTP常用的認(rèn)證方案,它通過Authorization請求消息頭含有服務(wù)器用于驗證用戶代理身份的憑證。格式為: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()中間件做一些簡單的用戶權(quán)限的認(rèn)證但當(dāng)使用了自定義的session時,Gin自帶的中間件則不能滿足需求此時可以編寫自定義的中間件,并且將自定義的中間件加入到全局中間件隊列中去每一個route的請求同樣會到自定義的中間件中去,實現(xiàn)自定義的認(rèn)證等因此,Gin的中間件大致可以分為兩類:全局中間件和路由中間件中間件的分類全局中間件作用于所有的路由上,所有的路由請求都需要經(jīng)過這些全局中間件。全局中間件局部中間件作用于單個路由,并不是所有路由路由中間件02中間件開發(fā)流程Next()Abort()Set()Get()2中間件開發(fā)流程Next()將請求傳遞給請求鏈中下一個處理方法當(dāng)執(zhí)行Next()的時候,程序會掛起當(dāng)前執(zhí)行的操作,并繼續(xù)向下執(zhí)行,等執(zhí)行完成下面的函數(shù),最后再反過來執(zhí)行該中間件,完成完整請求的執(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,"首頁") }) r.Run(":8080")}funccostTime()gin.HandlerFunc{ returnfunc(c*gin.Context){ //請求前獲取當(dāng)前時間
nowTime:=time.Now() //請求處理
c.Next() //處理后獲取消耗時間
costTime:=time.Since(nowTime) url:=c.Request.URL.String() fmt.Printf("therequestURL%scost%v\n",url,costTime) }}2中間件開發(fā)流程2中間件開發(fā)流程Abort()處理出現(xiàn)錯誤時,阻止當(dāng)前中間件之后的所有程序執(zhí)行,與return區(qū)別是Abort會繼續(xù)執(zhí)行當(dāng)前中間件,return會返回上一級,不會執(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,"首頁") }) r.Run(":8080")}funccostTime()gin.HandlerFunc{ returnfunc(c*gin.Context){ //請求前獲取當(dāng)前時間
nowTime:=time.Now() //請求處理
c.Abort() //處理后獲取消耗時間
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)前請求的相關(guān)信息,通過c.Set()存入,后續(xù)處理業(yè)務(wù)邏輯的函數(shù)中通過c.Get()來獲取當(dā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)//全局注冊中間件函數(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會話控制CookieSession3會話控制是服務(wù)器保存在瀏覽器上的一段信息瀏覽器有了Cookie,向服務(wù)器發(fā)送請求時都會同時將Cookie發(fā)送給服務(wù)器,服務(wù)器收到請求后,可以根據(jù)該信息處理請求Cookie由服務(wù)器創(chuàng)建,并發(fā)送給瀏覽器,最終由瀏覽器保存Cookie是服務(wù)器保存在瀏覽器上的一段信息瀏覽器有了Cookie,向服務(wù)器發(fā)送請求時都會同時將Cookie發(fā)送給服務(wù)器,服務(wù)器收到請求后,可以根據(jù)該信息處理請求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會話的key/value值maxAge表示過期時間path表示Cookie路徑domain表示作用域secure為true時Cookie只在HTTPS中生效httpOnly防止程序受到XSS攻擊。3會話控制c.SetCookie()3會話控制//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會話控制Cookie存在不安全明文、有上限存儲、帶寬消耗等各種問題HTTP協(xié)議無狀態(tài),服務(wù)器不能記錄瀏覽器的訪問狀態(tài)確定不同時刻的請求是否來自同一個客戶端而Session對象可以存儲特定用戶會話所需的屬性及配置信息當(dāng)用戶在應(yīng)用程序的Web頁之間跳轉(zhuǎn)時,存儲在Session對象中的變量將不會丟失,而是在整個用戶會話中一直存在下去當(dāng)用戶請求來自應(yīng)用程序的Web頁時,如果該用戶還沒有會話,則Web服務(wù)器將自動創(chuàng)建一個Session對象當(dāng)會話過期或被放棄后,服務(wù)器將終止該會話。Session對象最常見的一個用法就是存儲用戶的首選項Session依賴于Cookie,并且需要創(chuàng)建存儲引擎,設(shè)置密鑰Session3會話控制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會話控制packagemainimport( //導(dǎo)入session包
"/gin-contrib/sessions" //導(dǎo)入session存儲引擎
"/gin-contrib/sessions/cookie" //導(dǎo)入gin框架包
"/gin-gonic/gin")funcmain(){ r:=gin.Default() //創(chuàng)建基于cookie的存儲引擎,123456789參數(shù)是用于加密的密鑰
store:=cookie.NewStore([]byte("123456789")) //設(shè)置session中間件,參數(shù)mysession,指的是session的名字,也是cookie的名字
//store是前面創(chuàng)建的存儲引擎,我們可以替換成其他存儲引擎
r.Use(sessions.Sessions("mysession",store))3會話控制 r.GET("/hello",func(c*gin.Context){ //初始化session對象
session:=sessions.Default(c) //通過session.Get讀取session值
/*session是鍵值對格式數(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() //刪除整個session //session.Clear() } c.JSON(200,gin.H{"hello":session.Get("hello")}) }) r.Run(":8080")}04文件上傳MaxMultipartMemoryFormFile()SaveUploadedFile()MultipartForm()4文件上傳用于限制上傳文件的大小MaxMultipartMemoryFormFile()FormFile()用于獲取上傳文件的基本信息SaveUploadedFile()SaveUploadedFile()用于實現(xiàn)文件的保存MultipartForm()該方法實現(xiàn)對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等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 現(xiàn)澆樓蓋 課程設(shè)計
- 2025年度地下空間開發(fā)個人工程勞務(wù)分包合同范本4篇
- 2024年心理咨詢師題庫附答案(典型題)
- 二零二五版門衛(wèi)服務(wù)外包與社區(qū)安全防范系統(tǒng)承包4篇
- 2025年度草坪圍欄施工與智慧城市建設(shè)合同3篇
- 植筋膠施工方案
- 二零二五年度棉花品牌建設(shè)與推廣合同4篇
- 2024酒店宴會廳租賃與客戶服務(wù)協(xié)議版B版
- 地板磚拆除施工方案
- 工地跳板擋墻施工方案
- 2024年醫(yī)師定期考核臨床類考試題庫及答案(共500題)
- 2024年內(nèi)蒙古自治區(qū)專業(yè)技術(shù)人員繼續(xù)教育公需課考試答案
- 漳州市醫(yī)療保險參保人員門診特殊病種申請表
- 2023版押品考試題庫必考點含答案
- 2021年天津市初中學(xué)業(yè)考查試卷思想品德(開卷).
- 《城鎮(zhèn)燃?xì)庠O(shè)施運行、維護(hù)和搶修安全技術(shù)規(guī)程》(CJJ51-2006)
- 項目付款審核流程(visio流程圖)
- 循環(huán)系統(tǒng)詳細(xì)講解
- 榴園小學(xué)寒假留守兒童工作總結(jié)(共3頁)
- 初中物理-電功率大題專項
- 蘇州智能數(shù)控機床項目投資計劃書(模板)
評論
0/150
提交評論