获取已登录用户信息以供显示

huangapple go评论204阅读模式
英文:

Fetching Logged in User Info for display

问题

我正在使用https://github.com/kataras/iris Go web框架。我已经完成了以下步骤:

  1. 用户注册
  2. 用户验证和登录
  3. 创建并设置了一个名为username的键的会话,该键与用户(表和结构)的username相关联

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

// 在上面加载了所有的数据库和其他所需的值

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

在authcheck中间件中:

func authcheck(ctx context.Context) {
// 加载会话
// 获取会话键“isLoggedIn”
// 如果isLoggedIn == "no" 或者为空
// 重定向到登录页面
// 否则
ctx.Next()
}

我的会话函数:

func connectSess() *sessions.Sessions {
// 创建Gorilla SecureCookie会话
// 返回会话
}

现在,我的问题是,如何将已登录用户的值共享给模板中的所有路由。我目前的选项是:

// 加载所有的数据库和所需的值
allRoutes := app.Party("/", logThisMiddleware, authCheck) {

allRoutes.Get("/", func(ctx context.Context) {
    // 再次加载会话
    // 获取存储在会话中的用户名
    // 对数据库运行查询
    // 共享用户结构值
    // 例如 ctx.ViewData("user", user)
    ctx.View("index.html")
});

allRoutes.Get("dashboard", func(ctx context.Context) {
    // 再次加载会话
    // 获取存储在会话中的用户名
    // 对数据库运行查询
    // 共享用户结构值
    // 例如 ctx.ViewData("user", user)
    ctx.View("index.html")
});

}

但是上述代码的问题是,我将不得不为每个路由编写会话,并且对于我运行的每个路由都要再次运行查询,然后共享。

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

我需要一些关于如何优化这个过程并且只需编写一次代码而不是为每个路由重复以下步骤的想法:

// 再次加载会话
// 获取存储在会话中的用户名
// 对数据库运行查询
// 共享用户结构值
// 例如 ctx.ViewData("user", user)

英文:

I am using https://github.com/kataras/iris Go web framework. I have:

  1. User Registered
  2. User Verified & Logged in
  3. Session created and set with key username with user (table & struct) username

Now, here is my code for logged in user:

// Loaded All DB and other required value above

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

In authcheck middleware

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

My Session function

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

Now, my problem is, how do I share Logged User value to all routes in template. My Current option is:

// 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");
    });
}

But problem with above code is, I will have to write session for each route and run query again for each route I run and than share.

I feel, there must be better way of doing it , rather than loading session twice for each route one in authCheck middleware and second inside allRoutes.Get route.

I need ideas on how this can be optimised and user data can be shared to template by just writing code one time and not repeating below for each route

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

答案1

得分: 3

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

// 仅加载一次会话管理器
sess := connectSess()

func authCheck(ctx context.Context) {
    session := sess.Start(ctx)
    // 在这里加载用户。
    // [...]
    // 将返回的用户保存到此处理程序链的本地存储中,仅一次。
    ctx.Values().Set("user", user) // <-- 重要
}

app.Get("/", func(ctx context.Context) {
    // 从处理程序链的本地存储中获取用户。
    user := ctx.Values().Get("user") // <-- 重要

    // 将"user"绑定到用户实例。
    ctx.ViewData("user", user)
    // 渲染模板文件。
    ctx.View("index.html")
})

app.Get("dashboard", func(ctx context.Context) {
    // 同样,从本地存储中获取用户...
    user := ctx.Values().Get("user") // <-- 重要

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

就是这样,非常简单,对吧?

但是我有一些关于你的注意事项,如果你有更多时间,请阅读它们。

当你在根路径"/"时,你不需要为它创建一个party(.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 上有很多示例,祝你一切顺利!

英文:

it's easy you can use the ctx.Values().Set/Get to make something shareable between your route's handlers or middleware(s).

// 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(&quot;user&quot;, user) // &lt;-- IMPORTANT
}

app.Get(&quot;/&quot;, func(ctx context.Context) {
    // Get the user from our handlers chain&#39;s local storage.
    user := ctx.Values().Get(&quot;user&quot;) // &lt;-- IMPORTANT

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

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

    ctx.ViewData(&quot;user&quot;, user)
    ctx.View(&quot;index.html&quot;)
})

That's all, pretty simple, right?

But I have some notes for you, read them if you have more time.

When you're on root "/" you don't have to create a party for it(.Party) in order to add middlewares (begin(Use) or finish(Done)), use just the iris.Application instance, app.Use/Done.

Don't write this:

allRoutes := app.Party(&quot;/&quot;, logThisMiddleware, authCheck) {

    allRoutes.Get(&quot;/&quot;, myHandler)
}

Do that instead:

app.Use(logThisMiddleware, authCheck)
app.Get(&quot;/&quot;, myHandler)

It's easier to read and understand.

I've also noticed that you're using ; at the end of your functions, your editor and gocode tool will remove those, when you write a program using the Go Programming Language you shouldn't do that, remove all ;.

Last, please read the documentation and the examples, we have many of them at https://github.com/kataras/iris/tree/master/_examples , hopes you the best!

huangapple
  • 本文由 发表于 2017年9月9日 20:01:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/46130446.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定