前言
身份认证又称身份验证、鉴权,是指通过一定的手段,完成对用户身份的确认。对于服务端渲染和前后端分离这两种开发模式来说,分别有着不同的身份认证方案:服务端渲染推荐使用 Session 认证机制,前后端分离推荐使用 JWT 认证机制。通过这篇文章,我们来聊聊这两种认证机制。
HTTP 协议的无状态性
HTTP 协议的无状态性指的是客户端的每次 HTTP 请求都是独立的,连续多个请求之间没有直接的关系,服务器不会主动保留每次 HTTP 请求的状态。Cookie 和 Session 的主要目的就是为了弥补 HTTP 的无状态性。
Cookie
Cookie 是存储在用户浏览器中的一段不超过 4kB 的字符串。它由一个名称(Name)、一个值(Value)和其他几个用于控制 Cookie 有效期、安全性、使用范围的可选属性组成。
不同域名下的 Cookie 各自独立,每当客户端发起请求时,会自动把当前域名下所有 未过期 的 Cookie 一同发送到服务器。
Cookie 的几大特性:自动发送、域名独立、过期时限、4KB 限制
Cookie 在身份认证中的作用
客户端第一次请求服务器的时候,服务器通过 响应头的形式,向客户端发送一个身份认证的 Cookie,客户端会自动将 Cookie 保存在浏览器中。
之后当客户端浏览器每次请求服务器的时候,浏览器会自动将身份认证相关的 Cookie,通过 请求头的形式 发送给服务器,服务器即可验证客户端的身份。
Cookie 不具有安全性,不要使用 Cookie 存储重要且隐私的数据,比如用户的身份信息、密码等。
Session
Session 是一种记录服务器和客户端会话状态的机制,session 是基于 cookie 实现的,session 存储在 服务器端,sessionId 会被存储到客户端的 cookie 中。
Session 的工作原理
客户端第一次请求服务端时,服务端会根据用户提交的相关信息,创建对应的 Session,请求返回时将此 Session 的唯一标识信息 SessionID 返回给客户端。
客户端接收到服务器返回的 SessionID 后,将此信息存到 Cookie 中,同时 Cookie 记录此 SessionID 属于哪个域名。
之后客户端访问服务器时,请求会自动判断此域名下是否存在 Cookie 信息,如果存在自动将 Cookie 信息发送给服务端,服务端会从 Cookie 中获取 SessionID,再根据 SessionID 查找对应的 Session 信息,如果没有找到说明用户没有登录或者登录失效;如果找到 Session 证明用户已经登录可执行后面操作。
Session 认证的局限性
Session 认证机制需要配合 Cookie 才能实现。由于 Cookie 默认不支持跨域访问,所以当涉及到前端跨域请求后端接口时,需要做很多额外的配置,才能实现跨域 Session 认证。当前端需要 跨域请求 后端接口的时候,推荐使用 JWT 认证机制。
JWT
JWT(JSON Web Token) 是目前最流行的跨域认证解决方案。JWT 是一种认证授权机制。
JWT 的组成部分
JWT 通常由三部分组成,分别是 Header(头部)、Payload(有效荷载)、Signature(签名),三者之间使用 .
进行分隔。格式如下:
Header.Payload.Signature
Header 和 Signature 是安全性相关的部分,只是为了保证 Token 的安全性。 Payload 部分才是真正的用户信息,它是用户信息经过加密之后生成的字符串。
JWT 的工作原理
用户输入用户名/密码登录,服务端认证成功后,将用户的信息对象经过加密生成 Token 字符串发送给客户端。
客户端将 Token 存储到本地,一般是 LocalStorage 或 SessionStorage 中。
之后客户端再次发起请求时,通过请求头的 Authorization 字段,将 Token 发送给服务器,服务器把 Token 还原成用户的信息对象,认证成功后,服务器针对当前用户生成特定的响应内容给客户端。
Authorization 字段格式如下:
Authorization: Bearer <token>