基于cookie的用户登录状态管理

cookie是什么
先来花5分钟看完这篇文章:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Cookies
看完上文,相信大家对cookie已经有了一个整体的概念,我再强调一下,cookie是一个客户端概念,它是存储在浏览器本地的一小段文本(通常由服务器来生成这段文本)。
cookie的作用
如上文所说,cookie有许多作用,如会话状态管理,个性化设置,浏览器行为跟踪,客户端数据的存储等等。本篇文章就来讲讲基于cookie的用户登录状态管理。
插一句哈,一般提到cookie,还会有一个叫session的家伙和它一起出现,下篇文章我会讲到它,以及两者的区别。
cookie的产生过程

如上图所示,客户端携带账号和密码向服务器发起请求,服务器在校验通过后,通过HTTP Respose Header中的Set-Cookie头部,将一小段文本写入客户端浏览器,在以后的每个客户端HTTP Request Header的Cookie头部中会自动携带这段文本。
基于cookie的用户登录状态管理
下面我基于golang和gin框架(中间件使用比较舒服)来简单的实现一个基于cookie的用户登录状态管理demo
package main
import (
"net/http"
"time"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.GET("/login", Login)
// 需要登陆保护的
auth := r.Group("")
auth.Use(AuthRequired())
{
auth.GET("/me", UserInfo)
auth.GET("/logout", Logout)
}
r.Run("localhost:9000")
}
// 登陆
func Login(c *gin.Context) {
// 为了演示方便,我直接通过url明文传递账号密码,实际生产中应该用HTTP POST在body中传递
userID := c.Query("user_id")
password := c.Query("password")
// 用户身份校验(查询数据库)
if userID == "007" && password == "007" {
// 生成cookie
expiration := time.Now()
expiration = expiration.AddDate(0, 0, 1)
// 实际生产中我们可以加密userID
cookie := http.Cookie{Name: "userID", Value: userID, Expires: expiration}
http.SetCookie(c.Writer, &cookie)
c.JSON(http.StatusOK, gin.H{"msg": "Hello " + userID})
return
}
c.JSON(http.StatusBadRequest, gin.H{"msg": "账号或密码错误"})
}
// 检测是否登陆的中间件
func AuthRequired() gin.HandlerFunc {
return func(c *gin.Context) {
cookie, _ := c.Request.Cookie("userID")
if cookie == nil {
c.JSON(http.StatusUnauthorized, gin.H{"msg": "请先登陆"})
c.Abort()
}
// 实际生产中应校验cookie是否合法
c.Next()
}
}
// 查看用户个人信息
func UserInfo(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"msg": "007的个人页面"})
}
// 退出登陆
func Logout(c *gin.Context) {
// 设置cookie过期
expiration := time.Now()
expiration = expiration.AddDate(0, 0, -1)
cookie := http.Cookie{Name: "userID", Value: "", Expires: expiration}
http.SetCookie(c.Writer, &cookie)
c.JSON(http.StatusOK, gin.H{"msg": "退出成功"})
}
我们来看具体的演示流程和效果:



如下图所示,当我们退出后再去尝试访问个人页面时,会出现401没有权限的错误。

上述例子的缺点
先来说说上面的demo存在的问题吧,我们的退出登录函数本质是设置了一个过期了的cookie来覆盖以前发送给用户的正常cookie。
但是,这儿存在着一个重大的安全问题。如果用户将之前未过期的正常cookie记录下来(即本例子中的userID=007),即使调用了我们的logout接口,只要用户自己手动输入之前未过期的正常cookie,也是可以通过服务器的验证。
而且,最重要的是,我们无法让其失效,因为cookie的过期删除机制是由浏览器来控制的,但是当用户记录了cookie中的哪段文本后,在cookie到期后,浏览器只能删除存在于浏览器中的cookie,对用户自己记录下来的cookie确无能为力,也就是说这段cookie永远有效。(后面我们会讲一种叫json web token的技术,可以做到让我们签发的凭证自带过期机制,而不依赖浏览器)
当然,有同学会说,我们可以在服务器存储一份有效的cookie列表,在用户退出登录后,从有效列表中删除对应的cookie,这种在服务端维护用户状态的机制本质是session的思想,我们后面会讲基于session的用户登录状态管理。
再来说说cookie别的缺点:
当然这个我们通过设置cookie的属性为HttpOnly,来禁止JavaScript读取cookie值,可以起到一定的防护作用。
当然,cookie也是有优点的,我们把用户的登录状态保存在客户端,这样就不需要每一次去访问数据库来检测用户是否登录,减少了系统的IO开销。
最后
本文希望通过一个不是很完美的demo来讲述基于cookie的用户登录状态管理,下期我们来讲讲session。
基于cookie的用户登录状态管理的更多相关文章
- vue项目用户登录状态管理,vuex+localStorage实现
安装vuex cnpm install vuex --save-dev
- Asp.Net使用加密cookie代替session验证用户登录状态 源码分享
首先 session 和 cache 拥有各自的优势而存在. 他们的优劣就不在这里讨论了. 本实例仅存储用户id于用户名,对于多级权限的架构,可以自行修改增加权限字段 本实例采用vs2010编写 ...
- Django 用Session和Cookie分别实现记住用户登录状态
简介 由于http协议的请求是无状态的.故为了让用户在浏览器中再次访问该服务端时,他的登录状态能够保留(也可翻译为该用户访问这个服务端其他网页时不需再重复进行用户认证).我们可以采用Cookie或Se ...
- iOS开发之记录用户登录状态
iOS开发之记录用户登录状态 我们知道:CoreData的配置和使用步骤还是挺复杂的.但熟悉CoreData的使用流程后,CoreData还是蛮好用的.今天要说的是如何记录我们用户的登陆状态.例如微信 ...
- 第一百八十七节,jQuery,知问前端--cookie 插件,注册成功后生成cookie,显示登录状态
jQuery,知问前端--cookie 插件 学习要点: 1.使用 cookie 插件 2.注册直接登录 Cookie 是网站用来在客户端保存识别用户的一种小文件.一般来用库可以保存用户登 录信息.购 ...
- 基于jwt的用户登录认证
最近在app的开发过程中,做了一个基于token的用户登录认证,使用vue+node+mongoDB进行的开发,前来总结一下. token认证流程: 1:用户输入用户名和密码,进行登录操作,发送登录信 ...
- cookie实现用户登录验证
cookie实现用户登录验证 1, INSTALLED_APPS中注册app03 2,在主程序中新建映射关系到app3的url中 from django.conf.urls import url,in ...
- C# MVC 用户登录状态判断 【C#】list 去重(转载) js 日期格式转换(转载) C#日期转换(转载) Nullable<System.DateTime>日期格式转换 (转载) Asp.Net MVC中Action跳转(转载)
C# MVC 用户登录状态判断 来源:https://www.cnblogs.com/cherryzhou/p/4978342.html 在Filters文件夹下添加一个类Authenticati ...
- 关于用户登录状态存session,cookie还是数据库或者memcache的优劣
session中保存登陆状态: 优:整个应用可以从session中获取用户信息,并且查询时很方便.在session中保存用户信息是不可缺少的(web应用中) 缺:session中不宜保存大量信息,会增 ...
随机推荐
- SparkStreaming整合Flume的pull报错解决方案
先说下版本情况: Spark 2.4.3 Scala 2.11.12 Flume-1.6.0 Flume配置文件: simple-agent.sources = netcat-source simpl ...
- SQL SERVER 还原误操作导致还原无法停止,处理办法
昨天遇到运行库不知道单位哪个小伙子,把数据库还原了,导致单位业务全部瘫痪,主数据库一直显示正在还原,真的是不敢动,经过多方寻找,找到此脚本-------------------------数据库还原日 ...
- macOS10.14.2 gem 更新问题
macOS10.14.2,最近cocoapods不能正常使用了. 终端输入 sudo gem update –system 显示如下错误 ERROR: While executing gem … (G ...
- CS184.1X 计算机图形学导论 作业0
1.框架下载 在网站上下载了VS2012版本的作业0的框架,由于我的电脑上的VS是2017版的,根据提示安装好C++的版本,并框架的解决方案 重定解决方案目标为2017版本. 点击运行,可以出来界面. ...
- FLask中蓝图(用于分文件)
一,不使用蓝图,自己分文件 目录结构 -templates -views -__init__.py -user.py -order.py -app.py app.py from views impor ...
- JSON:JSON对象和JSON数组混排的复杂字符串
在java中的一个好用的JSON工具包:net.sf.json.JSONObject 和 net.sf.json.JSONArray 一 解析JSON对象和JSON数组类型混排的复杂字符串 举个例子: ...
- CSP-S 初赛内容整理
图灵奖 艾伦·麦席森·图灵(Alan Mathison Turing,1912-1954)1966 共计70名科学家获此殊荣,华人仅有1位,他是2000年姚期智. 解释型语言 Python / Jav ...
- 对新手严重不友好的强者——Nginx那些俯拾皆是的坑
1.if和后边的括号要隔一个空格,变量后面也要有空格. 2.location / 和location = / 的意味不一样.前面的是通用匹配,后面的匹配根节点访问请求,前面的使用不好很容易引发重定向过 ...
- 提权案例(一)渗透某asp.net网站通过sql server数据库public 提权 思路分享
先罗列出sql server 角色用户的权限 按照从最低级别角色(bulkadmin)到最高级别角色(sysadmin)的顺序进行描述:1.bulkadmin:这个角色可以运行BULK INSERT语 ...
- 张高兴的 .NET Core IoT 入门指南:(五)PWM 信号输出
什么是 PWM 在解释 PWM 之前首先来了解一下电路中信号的概念,其中包括模拟信号和数字信号.模拟信号是一种连续的信号,与连续函数类似,在图形上表现为一条不间断的连续曲线.数字信号为只能取有限个数值 ...