浅谈常见的认证机制
主流的认证机制
HTTP Basic Auth
这种是最初的使用用户名密码进行用户认证的,也就是每次请求都会携带用户密码,也是最不安全,最陈旧的方式。现在几乎不用
Cookie Auth
这种一般用于简单的项目中。原理是在用户第一次验证通过后将用户信息存入 Session 对象中,并且将 SessionID 以Cookie的形式发给客户端,以后每次客户端的请求都携带这个Cookie,服务器在接收后会先解析Cookie,如果找到符合的 Session 就通过。这种优点是配置简单,效率也比较高(用户基本信息不需要重复去查数据库)。缺点是由于 Cookie 的限制,不支持跨域,只支持统一域名下的请求访问。
OAuth
OAuth主要用于社交登陆中,由于 OAuth2 相比于 OAuth 更易上手,所以目前主要使用的是 OAuth2。其原理主要是先通过授权服务器获取访问令牌,再携带访问令牌去资源服务器获取资源。
具体模式主要有四种。
1、授权码模式。
最常用的,也是最安全的一种,首先通过第三方应用验证登陆,授权服务器返回 code,再通过 code 搭配 app_id、app_secret 来从授权服务器获取授权令牌,最终通过授权令牌访问资源服务器。优点是访问令牌token存储在服务器上,不会返回给客户端,不易被截取,同时code是一次性,使用一次后就失效,更安全。同时支持 refresh token,避免了 token 过期后需要重新验证的问题。这种方式主流应用于第三方平台的登陆。
2、简化模式:省去了获取code 的步骤,直接从认证服务器获取 token,是基于浏览器的应用,所以容易被截取 Token,这点可以通过减小 Token 的存活时间解决,但是不支持刷新 token,所以 token 过期后又无法使用。优点就是过程简单。这种方式因为直接返回给客户端,而不是在服务器之间交互,所以有安全风险。
3、密码模式:与简化模式大致一样,只不过是直接输入用户名、密码访问认证服务器来获取 token,因为是直接输入密码,所以需要认证的平台和当前平台有高度的信任。这种一般用于一家企业的两个产品平台上,同样因为是会和客户端交互,所以存在第三方恶意截获的风险
4、客户端凭证模式:这种方式是使调用放以应用的身份去访问而不是用户,所以在一次验证通过后,返回的 token 无平台限制,可以访问任意平台的资源。这种模式安全隐患也是最大的。
Token Auth
token 类似于 OAuth 模式,区别是传递的 token 不局限在 Cookie 中,一般存在 headers 的 Authorization 字段中,也可以存在 body ,甚至是 params里。其优点是不会和 Cookie 一样受到域名限制,但是如果是普通的 Token 那么后台在接受到会还需要去匹配对应的用户信息,造成操作次数过多,所以一般使用 JWT 来实现 Token Auth。JWT 是一个基于 json ,让我们在客户端与服务器端进行安全可靠信息交互的规范,其特点是本身可以存储一些数据,所以后台接受到 jwt 数据后可以直接解析获取用户信息,而不需要进行额外的查询。Token Auth可以预防 CSRF, CSRF 方式就是引诱你在已登录的浏览器上点击相关链接,如果你是 Cookie OAuth,那么点击发送的这次请求就会携带已登录网站的 Cookie,那么对方就会获取到你的 Cookie,进而登陆网站进行非法操作,而如果是 Token Auth,一般存储在 localStorage
中,那么即使点击了方法链接,也不会携带 Token,对方也就无法获取到访问令牌。
JWT
由于JWT 是一种规范,其实现方式有多种,在 Java 里一般使用 jjwt,所以这里就以 jjwt 为例来介绍其特点和使用
特点
1、组成部分:头部、载荷、签名。头部存储的是基本信息(类型,签名所用算法)。载荷存储的是有效信息( ID,用户,签发时间,存储数据等)。签名则是核心,因为前两部分是使用 base64 算法转换的,而 base64 是一种双向加密算法,也就是可以逆推,而签名是将前两部分结合盐进行加密组成的,所以即使当前 token 被截取到,其因为不知道盐值,所以不知道生成规则,保证了数据的安全性。
2、基于Json,方便解析。
3、令牌较长,占存储空间较大。
使用