还记得在上家公司作全干工程师的时候,基本从页面写到运维,当时作登陆这块的时候,被session、cookie、token各类概念差点整蒙圈了,上网查询相关概念,发现不少人都是相似的疑惑,好比:html
来了字节跳动以后,前端不多接触HTTP请求以后的事情,并且登陆相关的SDK封装的很好,因此这篇文章就简单的学习记录一下。前端
首先这是由于HTTP是无状态的协议,所谓无状态就是在两次请求之间服务器并不会保存任何的数据,至关于你和一我的说一句话以后他就把你忘掉了。因此,登陆就是用某种方法让服务器在屡次请求之间可以识别出你,而不是每次发请求都得带上用户名密码这样的识别身份的信息。 从登陆成功到登出的这个过程,服务器一直维护了一个能够识别出用户信息的数据结构,广义上来讲,这个过程就叫作session,也就是保持了一个会话。web
突然想到一点,看了网上不少问题,我以为你们应该区分两个概念:广义的session和狭义的session 算法
广义的session:广义的session就是从登陆成功到登出的过程,在这个过程当中客户端和服务器端维持了保持登陆的状态,至于具体怎么维持住这种登陆的状态,没有要求。json
狭义的session:狭义的session就是登陆成功后,服务器端存储了一些必须的用户信息,这部分存在服务器端的用户信息就叫作session,也就是接下来要说的第一种登陆的实现方式。后端
先用图来看: 跨域
详细说的说一下,这里面主要是这么几个过程:服务器
前面说到sessionId的方式本质是把用户状态信息维护在server端,token的方式就是把用户的状态信息加密成一串token传给前端,而后每次发请求时把token带上,传回给服务器端;服务器端收到请求以后,解析token而且验证相关信息;cookie
因此跟第一种登陆方式最本质的区别是:经过解析token的计算时间换取了session的存储空间session
业界通用的加密方式是jwt(json web token),jwt的具体格式如图:
简单的介绍一下jwt,它主要由3部分组成:
header 头部
{
"alg": "HS256",
"typ": "JWT"
}
payload 负载
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022,
"exp": 1555341649998
}
signature 签名
header里面描述加密算法和token的类型,类型通常都是JWT;
payload里面放的是用户的信息,也就是第一种登陆方式中须要维护在服务器端session中的信息;
signature是对前两部分的签名,也能够理解为加密;实现须要一个密钥(secret),这个secret只有服务器才知道,而后使用header里面的算法按照以下方法来加密:
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
总之,最后的 jwt = base64url(header) + "." + base64url(payload) + "." + signature
jwt能够放在response中返回,也能够放在cookie中返回,这都是具体的返回方式,并不重要。
客户端发起请求时,官方推荐放在HTTP header中:
Authorization: Bearer <token>
这样子确实也能够解决cookie跨域的问题,不过具体放在哪儿仍是根据业务场景来定,并无必定之规。
理清概念,一身轻松
--------------------------------------------
欢迎关注个人公众号,前端亚古兽,作前端,不止于作前端。