0

我正在使用https://github.com/kataras/iris Go 网络框架。我有:

  1. 用户注册
  2. 用户验证并登录
  3. 会话创建并username使用用户键设置(表和结构)username

现在,这是我的登录用户代码:

// Loaded All DB and other required value above

allRoutes := app.Party("/", logThisMiddleware, authCheck) {
    allRoutes.Get("/", func(ctx context.Context) {
        ctx.View("index.html");
    });
}

在 authcheck 中间件中

func authcheck(ctx context.Context) {
    // Loaded session.
    // Fetched Session key "isLoggedIn"
    // If isLoggedIn == "no" or "" (empty)
    // Redirected to login page
    // else
    ctx.Next()
}

我的会话功能

func connectSess() *sessions.Sessions {
    // Creating Gorilla SecureCookie Session
    // returning session
}

现在,我的问题是,如何将 Logged User 值共享给模板中的所有路由。我当前的选择是:

// Loaded all DB and required value
allRoutes := app.Party("/", logThisMiddleware, authCheck) {

    allRoutes.Get("/", func(ctx context.Context) {
        // Load Session again
        // Fetch username stored in session
        // Run Query against DB
        // Share the user struct value.
        // Example ctx.ViewData("user", user)
        ctx.View("index.html");
    });

    allRoutes.Get("dashboard", func(ctx context.Context) {
        // Load Session again
        // Fetch username stored in session
        // Run Query against DB
        // Share the user struct value.
        // Example ctx.ViewData("user", user)
        ctx.View("index.html");
    });
}

但是上面代码的问题是,我将不得不为每条路线编写会话,并为我运行的每条路线再次运行查询,而不是共享。

我觉得,必须有更好的方法来做到这一点,而不是为每个路由加载会话两次,其中一个在authCheck中间件中,第二个在内部allRoutes.Get路由中。

我需要关于如何优化这一点的想法,并且只需编写一次代码而不是在下面为每条路线重复,就可以将用户数据共享到模板

        // Load Session again
        // Fetch username stored in session
        // Run Query against DB
        // Share the user struct value.
        // Example ctx.ViewData("user", user)
4

1 回答 1

3

你可以很容易地使用ctx.Values().Set/Get来在你的路由的处理程序或中间件之间共享一些东西。

// load session manager once
sess := connectSess()

func authCheck(ctx context.Context) {
    session := sess.Start(ctx)
    // Load your user here.
    // [...]
    // Save the returning user to the local storage of this handlers chain, once. 
    ctx.Values().Set("user", user) // <-- IMPORTANT
}

app.Get("/", func(ctx context.Context) {
    // Get the user from our handlers chain's local storage.
    user := ctx.Values().Get("user") // <-- IMPORTANT

    // Bind the "{{.user}}" to the user instance.
    ctx.ViewData("user", user)
    // Render the template file.
    ctx.View("index.html")
})

app.Get("dashboard", func(ctx context.Context) {
    // The same, get the user from the local storage...
    user := ctx.Values().Get("user") // <-- IMPORTANT

    ctx.ViewData("user", user)
    ctx.View("index.html")
})

就是这样,很简单,对吧?

但是我有一些笔记给你,如果你有更多的时间阅读它们。

当你在 root "/" 上时,你不必为它创建一个派对(.Party)来添加中间件(begin(Use)或finish(Done)),只使用iris.Application实例,app.Use/Done.

不要这样写:

allRoutes := app.Party("/", logThisMiddleware, authCheck) {

    allRoutes.Get("/", myHandler)
}

改为这样做:

app.Use(logThisMiddleware, authCheck)
app.Get("/", myHandler)

它更容易阅读和理解

注意到您在;函数末尾使用,您的编辑器和gocode工具将删除它们,当您使用 Go 编程语言编写程序时,您不应该这样做,删除所有;.

最后,请阅读文档和示例,我们在https://github.com/kataras/iris/tree/master/_examples有很多,希望您一切顺利!

于 2017-09-10T10:10:41.413 回答