乐趣区

关于web:Go语言WEB框架使用说明使用拦截器验证用的户登录状态

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 main
import (
    "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>
退出移动版