WORM拦截器
WORM拦截器是一个action(处理器函数)之前或之后被调用的函数,通常用于解决一些公共逻辑。拦截器可能用于以下常见问题:
- 申请日志记录
- 错误处理
- 身份验证解决
WORM中有以下拦截器:
- before_exec :执行action之前拦截器
- after_exec :执行action之后拦截器
本文用一个例子来阐明如何应用拦截器来实现用户登录状态的断定。在这个例子中,用户拜访login_get来显示登录页面,并调用login_post页面来提交登录信息。在login_post页面中断定用户登录信息是否非法,并将登录账号保留在session中。用户拜访其余须要登录验证的页面(例如:index页面)前首先执行拦截器:handler.BeforeExec。在拦截器中获取用户账号,若没有获取到用户账号,则跳转到登录页面:login_get。应用拦截器来进行用户登录状态的查看的有点是,不必在每个处理器函数中都蕴含用户登录状态的查看逻辑。只有将登录逻辑独立进去,并实现为before_exec拦截器即可。以下时main函数的次要内容:
main函数
package mainimport ( "demo/handler" "github.com/haming123/wego" log "github.com/haming123/wego/dlog")func main() { web, err := wego.InitWeb() if err != nil { log.Error(err) return } wego.SetDebugLogLevel(wego.LOG_DEBUG) web.Config.SessionParam.SessionOn = true web.Config.SessionParam.HashKey = "demohash" web.BeforExec(handler.BeforeExec) web.GET("/login_get", handler.HandlerLoginGet).SkipHook() web.POST("/login_post", handler.HandlerLoginPost).SkipHook() web.GET("/index", handler.HandlerIndex) err = web.Run("0.0.0.0:8080") if err != nil { log.Error(err) }}
阐明:
- 本例子中应用基于cookie的session数据存储引擎,用于存储用户登录账号。
- 调用
web.BeforExec(handler.BeforeExec)
来设置拦截器,在handler.BeforeExec
拦截器中实现了登录状态的查看逻辑。 - 因为login_get页面、login_post页面不须要进行登录测验,应用
SkipHook()
来疏忽拦截器。
登录逻辑
用户拜访须要进行登录验证的页面时,首先会查看session的登录账号,若没有登录账号,则跳转到登录页面:login_get, 登录页面的处理器实现如下:
func HandlerLoginGet(c *wego.WebContext) { c.WriteHTML(http.StatusOK, "./view/login.html", nil)}
login.html的内容如下:
<!doctype html><html><head> <meta charset="UTF-8"> <title>登录页面</title></head><body><h2>用户登陆</h2><form action="/login_post" method="post"> <div>用户账号:</div> <div> <input type="text" name="account" placeholder="请输出用户账号" /> </div> <br /> <div>登录明码:</div> <div> <input type="password" name="password" placeholder="请输出登录明码"/> </div> <br /> <div> <input type="submit" value="立刻登录" /> </div></form></body></html>
用户点击"立刻登录"后项服务器发送post申请到login_post, login_post处理器的实现如下:
func HandlerLoginPost(c *wego.WebContext) { account := c.Param.MustString("account") password := c.Param.MustString("password") if account == "admin" && password == "demo" { c.Session.Set("account", account) c.Session.Save() c.Redirect(302, "/index") } else { c.Session.Set("account", "") c.Session.Save() c.Redirect(302, "/login_get") }}
阐明:
- 在HandlerLoginPost调用c.Session.Set将账号写入session。
登录拦截器的实现
登录查看的逻辑采纳before_exec拦截器来实现,以下是before_exec拦截器的代码:
func GetAccount(c *wego.WebContext) string { account, _ := c.Session.GetString("account") return account}func BeforeExec(c *wego.WebContext) { login_path := "/login_get" if GetAccount(c) == "" && c.Path != login_path { c.Redirect(302, login_path) return }}
阐明:
- 实现GetAccount函数来获取session数据,若用户胜利登录了零碎,则session中保留有用户的登录账号。在处理器函数中能够调用GetAccount函数来获取登录的登录账号。
- BeforeExec函数是before_exec拦截器的一个实现。在BeforeExec函数中首先调用GetAccount函数来获取登录的登录账号,若不存在用户账号,则跳转到登录页面:login_get,否则执行解决去函数。
index页面的实现
index页面须要验证用户是否登录,因为执行index页面的处理器前会执行before_exec拦截器, 因而在index页面的处理器函数中不须要再进行登录查看了,程序员只须要实现业务逻辑即可。index页面的处理器函数的实现代码如下:
func HandlerIndex(c *wego.WebContext) { c.WriteHTML(http.StatusOK, "./view/index.html", GetAccount(c))}
在HandlerIndex中读取index.html模板,并应用调用 GetAccount(c)获取用户账号,而后及进行渲染。其中index.html模板的内容如下:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title></head><body>hello : {{.}}</body></html>