首页 > 其他分享 >Go - Web Application 9

Go - Web Application 9

时间:2024-09-07 09:25:54浏览次数:14  
标签:Web use ctx request Application context Go our isAuthenticated

Using request context

At the moment our logic for authenticating a user consists of simply checking whether a "authenticatedUserID" value exists in their session data, like so:

func (app *application) isAuthenticated(r *http.Request) bool {
    return app.sessionManager.Exists(r.Context(), "authenticatedUserID")
}

We could make this check more robust by querying our users database table to make sure that the "authenticatedUserID" value is a real, valid value (i.e we haven’t deleted the user’s account since they last logged in).

But there is a slight problem with doing this additional database check.

Our isAuthenticated() helper can potentially be called multiple times in each request cycle. Currently we use it twice — once in the requireAuthentication() middleware and again in the newTemplateData() helper. So, if we query the database from the isAuthenticated() helper directly, we would end up making duplicated round-trips to the database during every request. And that’s not very efficient.

A better approach would be to carry out this check in some middleware to determine whether the current request is from an authenticated user or not, and then pass that information down to all subsequent handlers in the chain.

So how do we do this? Enter request context.

 

How request context works

Every http.Request that our middleware and handlers process has a context.Context object embedded in it, which we can use to store information during the lifetime of the request.

As I’ve already hinted at, in a web application a common use-case for this is to pass information between your pieces of middleware and other handlers.

In our case, we want to use it to check if a user is authenticated once in some middleware, and if they are, then make this information available to all our other middleware and handlers.

 

The request context syntax

The basic code for adding information to a request’s context looks like this:

// Where r is a *http.Request...
ctx := r.Context()
ctx = context.WithValue(ctx, "isAuthenticated", true)
r = r.WithContext(ctx)

Let’s step through this line-by-line.

  • First, we use the r.Context() method to retrieve the existing context from a request and assign it to the ctx variable.
  • Then we use the context.WithValue() method to create a new copy of the existing context, containing the key "isAuthenticated" and a value of true .
  • Then finally we use the r.WithContext() method to create a copy of the request containing our new context.

Important: Notice that we don’t actually update the context for a request directly. What we’re doing is creating a new copy of the http.Request object with our new context in it.

I should also point out that, for clarity, I made that code snippet a bit more verbose than it needs to be. It’s more typical to write it like this:

ctx = context.WithValue(r.Context(), "isAuthenticated", true)
r = r.WithContext(ctx)

So that’s how you add data to a request’s context. But what about retrieving it again?

The important thing to explain is that, behind the scenes, request context values are stored with the type any . And that means that, after retrieving them from the context, you’ll need to assert them to their original type before you use them.

To retrieve a value we need to use the r.Context().Value() method, like so:

isAuthenticated, ok := r.Context().Value("isAuthenticated").(bool)
if !ok {
    return errors.New("could not convert value to bool")
}

 

Avoiding key collisions

In the code samples above, I’ve used the string "isAuthenticated" as the key for storing and retrieving the data from a request’s context. But this isn’t recommended because there’s a risk that other third-party packages used by your application will also want to store data using the key "isAuthenticated" — and that would cause a naming collision.

To avoid this, it’s good practice to create your own custom type which you can use for your context keys. Extending our sample code, it’s much better to do something like this:

// Declare a custom "contextKey" type for your context keys.
type contextKey string

// Create a constant with the type contextKey that we can use.
const isAuthenticatedContextKey = contextKey("isAuthenticated")

...

// Set the value in the request context, using our isAuthenticatedContextKey constant as the key.
ctx := r.Context()
ctx = context.WithValue(ctx, isAuthenticatedContextKey, true)
r = r.WithContext(ctx)

...

// Retrieve the value from the request context using our constant as the key.
isAuthenticated, ok := r.Context().Value(isAuthenticatedContextKey).(bool)
if !ok {
    return errors.New("could not convert value to bool")
}

 

标签:Web,use,ctx,request,Application,context,Go,our,isAuthenticated
From: https://www.cnblogs.com/zhangzhihui/p/18401329

相关文章

  • trafilatura python web 数据获取库
    trafilaturapythonweb数据获取库,比较适合进行爬虫,数据提取,支持输出数据为csv,json,html,md,txt,xml包含的特性高级web爬虫以及文本发现并行处理在线以及离线输入内容灵活的配置支持,包含了元数据,格式,链接,表格多输出格式,包含了文本,markdown,json,html,xml额外扩展,支持语言检测,gui......
  • 计算机毕业设计必看必学!! 07558 Django校园宿舍管理系统,原创定制程序, java、PHP、py
    摘要本论文主要论述了如何使用django开发一个校园宿舍管理系统,本系统将严格按照软件开发流程进行各个阶段的工作,采用B/S架构,面向对象编程思想进行项目开发。在引言中,作者将论述校园宿舍管理系统的当前背景以及系统开发的目的,后续章节将严格按照软件开发流程,对系统进行各......
  • 【免费】springboot基于SringbootVue个人驾校预约管理系统--论文pf|毕业设计|Javaweb
    收藏点赞不迷路 关注作者有好处编号:springboot503springboot基于SringbootVue个人驾校预约管理系统--论文pf开发语言:Java数据库:MySQL技术:Spring+SpringMVC+MyBatis+Vue工具:IDEA/Ecilpse、Navicat、Maven1.系统展示2.万字文档展示第5章系统详细设计这个环节需要......
  • 【免费】springboot航班进出港管理系统|毕业设计|Javaweb项目
    收藏点赞不迷路 关注作者有好处编号:springboot402springboot航班进出港管理系统--论文pf开发语言:Java数据库:MySQL技术:Spring+SpringMVC+MyBatis+Vue工具:IDEA/Ecilpse、Navicat、Maven1.系统展示2.万字文档展示第5章系统详细设计   航班信息管理图5.1即为......
  • 毕业设计|springboot基于Java Web的考编论坛网站|免费|代码讲解
    收藏点赞不迷路 关注作者有好处编号:springboot333springboot基于JavaWeb的考编论坛网站的pf开发语言:Java数据库:MySQL技术:Spring+SpringMVC+MyBatis+Vue工具:IDEA/Ecilpse、Navicat、Maven1.系统展示2.万字文档展示第5章系统详细设计这个环节需要使用前面的设计......
  • JAVA毕业设计|(免费)springboot基于Java Web的考编论坛网站包含文档代码讲解
    收藏点赞不迷路 关注作者有好处编号:springboot333springboot基于JavaWeb的考编论坛网站的pf开发语言:Java数据库:MySQL技术:Spring+SpringMVC+MyBatis+Vue工具:IDEA/Ecilpse、Navicat、Maven1.系统展示2.万字文档展示第5章系统详细设计这个环节需要使用前面的设计......
  • JAVA毕业设计|(免费)springboot基于Java Web的考编论坛网站包含文档代码讲解
    收藏点赞不迷路 关注作者有好处编号:springboot333springboot基于JavaWeb的考编论坛网站的pf开发语言:Java数据库:MySQL技术:Spring+SpringMVC+MyBatis+Vue工具:IDEA/Ecilpse、Navicat、Maven1.系统展示2.万字文档展示第5章系统详细设计这个环节需要使用前面的设计......
  • How to create the Gold gold using RGB color values All In One
    HowtocreatetheGoldgoldusingRGBcolorvaluesAllInOne如何使用RGB颜色值创建金色Gold(Golden)ColorColorName: Gold(Golden)HexColorCode:#FFD700RGBColorCode:RGB(255,215,0)CMYKValues*:0.0%,15.7%,100.0%,0.0%ColorFamily(Hue):Yell......
  • 475. 简单的学校网页 大学生期末大作业 Web前端网页制作 html+css
    目录一、网页概述二、网页文件 三、网页效果四、代码展示1.html2.CSS五、总结1.简洁实用2.使用方便3.整体性好4.形象突出5.交互式强六、更多推荐欢迎光临仙女的网页世界!这里有各行各业的Web前端网页制作的案例,样式齐全新颖,并持续更新!感谢CSDN,提供了这么好......
  • 受 LabelImg 启发的基于 web 的图像标注工具,基于 Vue 框架
    受LabelImg启发的基于web的图像标注工具,基于Vue框架  哟,网友们好,年更鸽子终于想起了他的博客园密码。如标题所述,今天给大家带来的是一个基于vue2的图像标注工具。至于它诞生的契机呢,应该是我导pass掉了我的提议(让甲方使用LabelImg进行数据标注),说是要把功能集成起来......