热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

asp.netjavascrip获取session的值_GoWeb编程SecureCookie实现客户端Session管理

GoWeb编程--SecureCookie实现客户端Session管理在Web应用开发中Session是在用户和服务器之间进行交换的非持久化交互信息。当用户登录时,可

Go Web编程--SecureCOOKIE实现客户端Session管理

在Web应用开发中Session是在用户和服务器之间进行交换的非持久化交互信息。当用户登录时,可以在用户和服务器之间生成Session,然后来回交换数据,并在用户登出时销毁Session。gorilla/sessions软件包提供了易于使用的Go语言Session实现。该软件包提供了两种不同的实现。第一个是文件系统存储,它将每个会话存储在服务器的文件系统中。另一个是COOKIE存储,它使用我们上篇文章讲的SecureCOOKIE在客户端上存储会话。同时还提供了用户自定义Session存储实现的选项,我们可以根据应用的需求自己实现Session存储。因为我们的教程是学会使用为目的就不大费周章的去实现MySQL或者Redis版本的Session存储了,我们直接使用软件包提供的COOKIE实现来完成本节的Session相关内容。

Go Web 编程系列的每篇文章的源代码都打了对应版本的软件包,供大家参考。公众号中回复gohttp09获取本文源代码

使用COOKIE存储用户Session的优缺点

客户端使用COOKIE管理用户Session较之在服务器进行用户的Session管理会有一些优势。客户端Session增加了应用程序的可伸缩性,因为所有的会话数据都存储在用户端,因此可以将用户的请求平衡到不同的远端服务器,也不必在服务器端对所有用户的会话进行统一管理,所以使用COOKIE存储用户Session会更简单一些。

当然有优势就必定有劣势,客户端COOKIE的整体大小是有限制的。目前,Google Chrome浏览器将COOKIE限制为4096个字节。

客户端会话还意味着无法终止会话,从而导致注销不完整。如果用户在退出前保存了COOKIE中的会话信息,则他们可以使用该会话信息创建一个新的COOKIE,然后继续使用该应用程序,为了最大程度地降低安全风险,我们可以将会话COOKIE设置为在合理的时间内过期,使用加密后的ScureCOOKIE存储数据,同时还要避免在其中存储敏感信息(即使是服务端管理Session也不应该存储类似密码这种敏感信息)。

总之在考虑使用客户端还是服务端存储用户Session时一定要根据应用的使用场景来选择,这一点很重要。

安装gorilla/sessions

在开始编码前先来安装一下gorilla/sessions软件包,

$ go get github.com/gorilla/sessions

并简单看一下软件包功能特性的介绍

  • 方便地设置签名(也可以选择加密)的COOKIE。
  • 自带将会话存储在COOKIE或服务端文件系统中的SessionStore实现。
  • 支持Flash消息:读取即销毁的会话数据。
  • 支持方便地切换会话数据的持久化方式。
  • 为不同的Session存储提供统一的接口和基础设施。

演示用户Session设计实现

我们今天的示例代码是用gorilla/sessions提供的COOKIESessionStore实现一个简单的系统登录功能。

我们会定义如下几个路由:

  • /user/login 用户登录验证,验证成功后在用户Session数据中标记用户是已验证的。
  • /user/logout 用户登出,会在Session中标记用户是未认证的。
  • /user/secret 通过用户Session判断用户是否已认证,未认证返回403 Forbidden错误。

为了达到演示目的的同时减少文章中出现过多代码,我们不会做前端页面,通过命令行cURL直接请求上面几个URL验证我们的系统登录功能。

初始化工作

我们现在项目的handler目录下新建一个user子目录,用于存放使用到用户Session的处理程序

...handler/└── user/ └── init.go └── login.go └── logout.go └── secret.go...main.go

其下的四个分别是包的初始化程序init.go以及存放上面说的三个路由处理程序的.go源文件。

初始化Session存储

我们把Session存储的初始化工作放在user包的init函数中,这样首次导入user包时即可完成相关的初始化工作。

package userimport "github.com/gorilla/sessions"const (//64位COOKIEStoreAuthKey = "..."//AES encrypt key必须是16或者32位COOKIEStoreEncryptKey = "...")var sessionStore *sessions.COOKIEStorefunc init () {sessionStore = sessions.NewCOOKIEStore([]byte(COOKIEStoreAuthKey),[]byte(COOKIEStoreEncryptKey),)sessionStore.Options = &sessions.Options{HttpOnly: true,MaxAge: 60 * 15,}}

实现登录验证

// login.govar sessionCOOKIEName = "user-session"func Login(w http.ResponseWriter, r *http.Request) {session, err := sessionStore.Get(r, sessionCOOKIEName)if err != nil {http.Error(w, err.Error(), http.StatusInternalServerError)return}// 登录验证name := r.FormValue("name")pass := r.FormValue("password")_, err = logic.AuthenticateUser(name, pass)if err != nil {http.Error(w, err.Error(), http.StatusUnauthorized)return}// 在session中标记用户已经通过登录验证session.Values["authenticated"] = trueerr = session.Save(r, w)fmt.Fprintln(w, "登录成功!", err)}

  • 我们将浏览器COOKIE中存储用户Session的COOKIE-Name设置成了user-session。
  • 登录验证就是简单的用户名和密码查找匹配的用户,在之前的文章应用数据库和应用 ORM两篇文章中有在MySQL数据库中创建users表,并介绍了怎么使用ORM操作数据库,没有看过的同学可以回看一下。
  • 登录验证成功后在Session的authenticated中标记了用户已通过认证。session.Values是类型map[interface{}]interface{}的别名,所以可以往其中存储任意类型的数据。

实现登出

登出我们这里就是简单的将Session中authenticated的值设置成了false.

//logout.gofunc Logout(w http.ResponseWriter, r *http.Request) { session, _ := sessionStore.Get(r, sessionCOOKIEName) session.Values["authenticated"] = false session.Save(r, w)}

使用Session认证用户

//secret.gofunc Secret(w http.ResponseWriter, r *http.Request) { session, _ := sessionStore.Get(r, sessionCOOKIEName) if auth, ok := session.Values["authenticated"].(bool); !ok || !auth { http.Error(w, "Forbidden", http.StatusForbidden) return } fmt.Fprintln(w, "这里还是空空如也!")}

  • 使用Session中存储的数据值都是接口类型的,所以使用时要先对其进行类型断言session.Values["authenticated"].(bool)
  • 如果authenticated的值不为true或者是从Session中获取不到对应的值,这里直接返回HTTP 403 Forbidden错误。

注册路由

// router.gofunc RegisterRoutes(r *mux.Router) { ... userRouter := r.PathPrefix("/user").Subrouter() userRouter.HandleFunc("/login", user.Login).Methods("POST") userRouter.HandleFunc("/secret", user.Secret) userRouter.HandleFunc("/logout", user.Logout) ...}

验证已实现的Session管理功能

编写完上面的Session管理的功能后,重启服务器,然后使用cURL分别请求URL验证一下效果。

curl -XPOST -d 'name=Klein&password=123' -c - http://localhost:8000/user/login

-c选项表示将COOKIE写入到后面的文件中,完整格式是-c -,短横线后不带文件名表示把COOKIE写入到标准输出中。

我们可以在下图里看到,COOKIE中的user-session存储的就是加密后的Session数据了

f8dcb8135a1649e797afe4bc4ed2f12f

如果请求中不携带这个COOKIE访问/user/secret会直接返回HTTP 403错误

a0fc5a7704b74d0595ff2e558b6754e8

那么接下来在使用cURL请求/user/secret时带上上面返回的COOKIE值,看看请求是否能成功

curl --COOKIE "user-session=MTU4m..." http://localhost:8000/user/secret

b3d840239d624f2ba3d54082f3ac3851

COOKIE加密后的值太长了,搞得字儿好小,cURL执行的结果显示服务器成功地响应了我们的请求。你们试验的时候换成自己生成的COOKIE值请求就可以啦。

你们实践时也可以用PostMan代替cURL试验,不过感觉PostMan的返回不如cURL来的明显。



推荐阅读
  • 搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的详细步骤
    本文详细介绍了搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的步骤,包括环境说明、相关软件下载的地址以及所需的插件下载地址。 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • Metasploit攻击渗透实践
    本文介绍了Metasploit攻击渗透实践的内容和要求,包括主动攻击、针对浏览器和客户端的攻击,以及成功应用辅助模块的实践过程。其中涉及使用Hydra在不知道密码的情况下攻击metsploit2靶机获取密码,以及攻击浏览器中的tomcat服务的具体步骤。同时还讲解了爆破密码的方法和设置攻击目标主机的相关参数。 ... [详细]
  • 本文介绍了Perl的测试框架Test::Base,它是一个数据驱动的测试框架,可以自动进行单元测试,省去手工编写测试程序的麻烦。与Test::More完全兼容,使用方法简单。以plural函数为例,展示了Test::Base的使用方法。 ... [详细]
  • 本文介绍了在Mac上搭建php环境后无法使用localhost连接mysql的问题,并通过将localhost替换为127.0.0.1或本机IP解决了该问题。文章解释了localhost和127.0.0.1的区别,指出了使用socket方式连接导致连接失败的原因。此外,还提供了相关链接供读者深入了解。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • 本文详细介绍了GetModuleFileName函数的用法,该函数可以用于获取当前模块所在的路径,方便进行文件操作和读取配置信息。文章通过示例代码和详细的解释,帮助读者理解和使用该函数。同时,还提供了相关的API函数声明和说明。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • javascript  – 概述在Firefox上无法正常工作
    我试图提出一些自定义大纲,以达到一些Web可访问性建议.但我不能用Firefox制作.这就是它在Chrome上的外观:而那个图标实际上是一个锚点.在Firefox上,它只概述了整个 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • ZSI.generate.Wsdl2PythonError: unsupported local simpleType restriction ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
author-avatar
rorather_0979107
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有