{{define "users/login.html"}}
<! DOCTYPE  html > < htmllang = " en" > < head> < metacharset = " UTF-8" > < title> </ title> </ head> < body> < formmethod = " post" action = " /login" > < inputstyle = " align-content :  center" type = " text" name = " username" onfocus = " change ( ) " > < br/> < inputtype = " password" name = " password" onfocus = " change ( ) " > < br/> < inputtype = " submit" value = " login" > </ form> < h1id  =  " tag" style = " color :  red" > </ h1> </ body> < script> function  change ( )  { let  tag =  document. getElementById ( "tag" ) ; tag. innerHTML= "<h1></h1>" ; } 
</ script> </ html> {{define "default/index.html"}}
<! DOCTYPE  html > < htmllang = " en" > < head> < metacharset = " UTF-8" > < title> </ title> </ head> < body> < h1style = " color :  chocolate;  align-content :  center" > </ h1> </ body> </ html> package  controllersimport  ( "github.com/gin-contrib/sessions" "github.com/gin-gonic/gin" "net/http" 
) package  controllerstype  Auth struct  { Username string Password string 
} const  DefaultAuthInfoKey =  "AUTH" func  LoginGet ( )  gin. HandlerFunc { return  func ( ctx * gin. Context)  { ctx. HTML ( http. StatusOK,  "users/login.html" ,  nil ) } 
} func  LogoutGet ( )  gin. HandlerFunc { return  func ( ctx * gin. Context)  { session :=  sessions. Default ( ctx) session. Delete ( DefaultAuthInfoKey) session. Options ( sessions. Options{ Path:      "/" , Domain:    "localhost" , MaxAge:    0 , Secure:    true , HttpOnly:  false , SameSite:  0 , } ) session. Save ( ) ctx. Redirect ( http. StatusFound,  "/login" ) ctx. Abort ( ) } 
} func  LoginPost ( )  gin. HandlerFunc { return  func ( ctx * gin. Context)  { username :=  ctx. PostForm ( "username" ) password :=  ctx. PostForm ( "password" ) if  username !=  "admin"  ||  password !=  "admin"  { ctx. HTML ( http. StatusOK,  "users/login.html" ,  gin. H{ "Message" :  "用户名或密码错误!" , } ) ctx. Abort ( ) return } auth :=  Auth{ Username:  username,  Password:  password} ctx. Set ( DefaultAuthInfoKey,  auth) session :=  sessions. Default ( ctx) session. Set ( DefaultAuthInfoKey,  auth) session. Save ( )  ctx. Redirect ( http. StatusFound,  "/" ) } 
} func  Index ( )  gin. HandlerFunc { return  func ( ctx * gin. Context)  { ctx. HTML ( http. StatusOK,  "default/index.html" ,  gin. H{ "Content" :  "欢迎回来:"  +  ctx. MustGet ( DefaultAuthInfoKey) . ( Auth) . Username, } ) } 
} 
package  routersimport  ( "encoding/gob" "github.com/coolbit/gin_sample/controllers" "github.com/coolbit/gin_sample/middleware" "github.com/gin-contrib/sessions" "github.com/gin-contrib/sessions/cookie" "github.com/gin-gonic/gin" "net/http" 
) var  router * gin. Enginefunc  GetRouter ( )  * gin. Engine { return  router
} func  AuthRequired ( )  gin. HandlerFunc { return  func ( ctx * gin. Context)  { session :=  sessions. Default ( ctx) auth :=  session. Get ( controllers. DefaultAuthInfoKey) au,  ok :=  auth. ( controllers. Auth) if  ! ok ||  au. Username ==  ""  { ctx. Redirect ( http. StatusFound,  "/login" ) ctx. Abort ( ) return } ctx. Set ( controllers. DefaultAuthInfoKey,  auth)  session. Options ( sessions. Options{              Path:      "/" , Domain:    "localhost" , MaxAge:    7  *  24  *  60  *  60 ,  Secure:    true , HttpOnly:  false , SameSite:  0 , } ) session. Set ( controllers. DefaultAuthInfoKey,  au) session. Save ( )  } 
} func  init ( )  { router =  gin. Default ( ) router. MaxMultipartMemory =  8  <<  20  router. Static ( "/static" ,  "static" ) router. LoadHTMLGlob ( "views/**/*" ) gob. Register ( controllers. Auth{ } )  store :=  cookie. NewStore ( [ ] byte ( "我是密钥" ) ) router. Use ( sessions. Sessions ( "SESSION_ID" ,  store) ) router. GET ( "/login" ,  controllers. LoginGet ( ) ) router. POST ( "/login" ,  controllers. LoginPost ( ) ) router. Use ( AuthRequired ( ) )  router. GET ( "/" ,  controllers. Index ( ) ) 
} 
package  mainimport  ( "github.com/coolbit/gin_sample/routers" 
) func  main ( )  { routers. GetRouter ( ) . Run ( ":80" ) 
} 
客户端发起http://localhost/请求。 请求须经过后端AuthRequired中间件鉴权。该中间件查看session中是否保存了请求携带的cookie对应的用户信息,若有。则登录成功;若没有,则重定向到http://localhost/login进行登录。 GET方法请求http://localhost/login时只返回页面,不需鉴权逻辑。 POST方法请求http://localhost/login时,不需鉴权逻辑。进行登录验证,并记录session,为当前context设置Key为"AUTH"的有效用户信息。方便该次请求链路使用。登录成功则重定向到http://localhost/。