Token&Cookies&Session
title: Token&Cookies&Session
date: 2018-04-19 19:52:01
tags: [vue,token,cookies,session,login]
categories: 前端技术
---
最近遇到前后端验证登陆的问题,学习并记录如何验证。现在许多的大型网站已经采用Token的方式进行验证,简化了验证流程。百度百科称token是一种令牌机制,实际上就是一串加密的字符串,通过解密来验证是否登陆。
传统验证登陆的方法
HTTP 是一种没有状态的协议,也就是它并不知道是谁是访问应用。这里我们把用户看成是客户端,客户端使用用户名还有密码通过了身份验证,不过下回这个客户端再发送请求时候,还得再验证一下。
解决的方法就是,当用户请求登录的时候,如果没有问题,我们在服务端生成一条记录,这个记录里可以说明一下登录的用户是谁,然后把这条记录的 ID 号发送给客户端,客户端收到以后把这个 ID 号存储在 Cookie 里,下次这个用户再向服务端发送请求的时候,可以带着这个 Cookie ,这样服务端会验证一个这个 Cookie 里的信息,看看能不能在服务端这里找到对应的记录,如果可以,说明用户已经通过了身份验证,就把用户请求的数据返回给客户端。
上面说的就是 Session,我们需要在服务端存储为登录的用户生成的 Session ,这些 Session 可能会存储在内存,磁盘,或者数据库里。我们可能需要在服务端定期的去清理过期的 Session 。
基于Token的验证方法
采用Token的验证方式,需要将Token字符串在本地记录,一般使用LocalStorage或者SessionStorage在本地储存起来。具体流程如下:
- 客户端使用用户名跟密码请求登录
- 服务端收到请求,去验证用户名与密码
- 验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端
- 客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里
- 客户端每次向服务端请求资源的时候需要带着服务端签发的 Token
- 服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据
JWT
实现token的方式可以有很多,JWT是其中的一种方式,其实本质上只是一个字符串,无论什么字符串都可以,但需要保证加密的可靠性,以及相关的标准,这样比较符合开发逻辑。这种验证方式的Token包含三个部分,具体如下:
- header
- payload
- signature
三部分使用“,”隔开,并且使用base64编码。实例如下:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJuaW5naGFvLm5ldCIsImV4cCI6IjE0Mzg5NTU0NDUiLCJuYW1lIjoid2FuZ2hhbyIsImFkbWluIjp0cnVlfQ.SwyHTEx_RQppr97g4J5lKXtabJecpejuef8AqKYMAJc
Header
header 部分主要是两部分内容,一个是 Token 的类型,另一个是使用的算法,比如下面类型就是 JWT,使用的算法是 HS256。
{             "typ": "JWT",       "alg": "HS256"    }
上述字符通过Base64编码后得到eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
Payload
Payload 里面是 Token 的具体内容,这些内容里面有一些是标准字段,你也可以添加其它需要的内容。下面是标准字段:
- iss:Issuer,发行者
- sub:Subject,主题
- aud:Audience,观众
- exp:Expiration time,过期时间
- nbf:Not before
- iat:Issued at,发行时间
- jti:JWT ID
例如:
{      "iss": "ninghao.net",  "exp": "1438955445",  "name": "wanghao",  "admin": true }
Signature
JWT 的最后一部分是 Signature ,这部分内容有三个部分,先是用 Base64 编码的 header.payload ,再用加密算法加密一下,加密的时候要放进去一个 Secret ,这个相当于是一个密码,这个密码秘密地存储在服务端。
- header
- payload
- secret - var encodedString = base64UrlEncode(header) + "." + base64UrlEncode(payload); 
 HMACSHA256(encodedString, 'secret');
处理完成以后看起来像这样:
SwyHTEx_RQppr97g4J5lKXtabJecpejuef8AqKYMAJc
最后这个在服务端生成并且要发送给客户端的 Token 看起来像这样:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJuaW5naGFvLm5ldCIsImV4cCI6IjE0Mzg5NTU0NDUiLCJuYW1lIjoid2FuZ2hhbyIsImFkbWluIjp0cnVlfQ.SwyHTEx_RQppr97g4J5lKXtabJecpejuef8AqKYMAJc
客户端收到这个 Token 以后把它存储下来,下回向服务端发送请求的时候就带着这个 Token 。服务端收到这个 Token ,然后进行验证,通过以后就会返回给客户端想要的资源。
Token使用中需要注意的几点
- Token 应该被保存起来,放到 local / session stograge 或者 cookies
- Tokens 除了像 cookie 一样有有效期,而且可以有更多的操作方法
- 有需要的话,要加密并且签名 token
- Tokens 不是万能的解决方法,得根据你的需求自行采用
- 将 JSON Web Tokens 应用到 OAuth 2
相关链接:
Token&Cookies&Session的更多相关文章
- 转-Android客户端和服务端如何使用Token和Session
		http://www.software8.co/wzjs/yidongkaifa/6407.html 对于初学者来说,对Token和Session的使用难免会限于困境,开发过程中知道有这个东西,但却不 ... 
- ASP.NET Core 2 学习笔记(十一)Cookies & Session
		基本上HTTP是没有记录状态的协定,但可以通过Cookies将Request来源区分出来,并将部分数据暂存于Cookies及Session,是写网站常用的用户数据暂存方式.本篇将介绍如何在ASP.NE ... 
- 客户端和服务端如何使用Token和Session
		一.我们先解释一下他的含义: 1.Token的引入:Token是在客户端频繁向服务端请求数据,服务端频繁的去数据库查询用户名和密码并进行对比,判断用户名和密码正确与否,并作出相应提示,在这样的背 ... 
- 为什么要使用token,token与session区别是什么
		目录 一.session的状态保持及弊端 二.token认证机制 一.session的状态保持及弊端 当用户第一次通过浏览器使用用户名和密码访问服务器时,服务器会验证用户数据,验证成功后在服务器端写入 ... 
- django form组件  cookies,session
		django form组件 渲染标签 就是组件里面的字段在前端展示叫做渲染标签 校验数据 用户输入的数据提交给后端组件叫做校验数据 forms组件中定义的字段都是必须传值的(required=Tr ... 
- token和session的区别及其发展史
		其实token与session的问题是一种时间与空间的博弈问题, session是空间换时间,而token是时间换空间. 一.发展史 很久很久以前,Web 基本上就是文档的浏览而已, 既然是浏览,作为 ... 
- web 存储方式汇总:Cookies,Session, Web SQL; Web Storage(LocalStorage ,SessionStorage),IndexedDB,Application Cache,Cache Storage
		1 1 1 web 存储方式汇总: 旧的方式: Cookies; Session; Web SQL; 新的方式 HTML5 : Web Storage(LocalStorage ,SessionSto ... 
- jwt, token, session和cookies
		jwt token,session和cookies 
- cookies, session, token
		Cookie 是由客户端(通常是浏览器)保存的小型文本信息,其内容是一系列的键值对,是由 HTTP 服务器设置并保存在浏览器上的信息. 在post请求的瞬间,cookie会被浏览器自动添加到请求头中. ... 
随机推荐
- centos7下搭建高匿HTTP代理
			一.一般适用情况1.两台都有外网IP,一台服务器请求资源通过另外一个服务器,本文重点讲第一种.2.两台服务器,其中一台服务器只有内网IP,另外一台服务器有公网和内网IP. 二.前提 # 确认服务器端i ... 
- Java提高篇(一):区分引用变量与对象
			我们有代码: New A=new New(); 下面是这个New的类: class New { public New() { System.out.println("这是New类当中的构造方 ... 
- Ubuntu 16.04安装Nginx
			在Ubuntu下安装Nginx有以下方法,但是如果想要安装最新版本的就必须下载源码包编译安装. 一.基于APT源安装 sudo apt-get install nginx 安装好的文件位置: /usr ... 
- MyEclipse设置Console输出到文件
			Java程序默认输出为Console,如果要想将Console输出结果保存到文件中,则需要做如下配置: 在JAVA程序上右键--> Run As --> Run Configuration ... 
- [Swift]LeetCode930. 和相同的二元子数组 | Binary Subarrays With Sum
			In an array A of 0s and 1s, how many non-empty subarrays have sum S? Example 1: Input: A = [1,0,1,0, ... 
- [Swift]LeetCode978. 最长湍流子数组 | Longest Turbulent Subarray
			A subarray A[i], A[i+1], ..., A[j] of A is said to be turbulent if and only if: For i <= k < j ... 
- SpringBoot + SpringCloud学习踩坑实记
			踩的坑: 1).springcloud框架中,依赖一直报错,很可能是没有添加springcloud的依赖,或者是依赖的版本号过低.并且springboot也有一个父依赖. 2.springcloud ... 
- mybatis xml  <  >
			[参考文章]:mybatis 中的 xml 配置文件中 ‘<’. ‘>’ 处理 1.使用转义字符将 ‘<’. ‘>’ 替换掉 描述 字符 转义字符小于号 < <大于 ... 
- Hibernate框架笔记04HQL_QBC查询详解_抓取策略优化机制
			目录 1. Hibernate的查询方式 1.1 方式一:OID查询 1.2 方式二:对象导航查询 1.3 方式三:HQL方式 1.4 方式四:QBC查询 1.5 方式五:SQL查询 2. 环境搭建 ... 
- spark System memory must be at least
			运行 ScalaSpark 程序的时候出现错误: System memory * must be at least *.Please increase heap size using the --dr ... 
