首页  /  世界杯意大利  /  登录认证全解析

登录认证全解析

世界杯意大利 3806

1.Cookie + Session 登录

HTTP 是一种无状态的协议,客户端每次发送请求时,首先要和服务器端建立一个连接,在请求完成后又会断开这个连接。这种方式可以节省传输时占用的连接资源,但同时也存在一个问题:每次请求都是独立的,服务器端无法判断本次请求和上一次请求是否来自同一个用户,进而也就无法判断用户的登录状态。

为了解决 HTTP 无状态的问题,Lou Montulli 在 1994 年的时候,推出了 Cookie。

Cookie 是服务器端发送给客户端的一段特殊信息,这些信息以文本的方式存放在客户端,客户端每次向服务器端发送请求时都会带上这些特殊信息。

有了 Cookie 之后,服务器端就能够获取到客户端传递过来的信息了,如果需要对信息进行验证,还需要通过 Session。

客户端请求服务端,服务端会为这次请求开辟一块内存空间,这个便是 Session 对象。

有了 Cookie 和 Session 之后,我们就可以进行登录认证了。

实现流程:

Cookie + Session 的登录方式是最经典的一种登录方式,现在仍然有大量的企业在使用。

用户首次登录时:

1.用户访问A网站的页面a,输入密码。

2.服务器验证账号密码。

3.验证成功,创建并保存SessionID。

4.服务器响应客户端的HTTP请求,并通过Set-Cookie头信息把SessionId写入Cookie。

*服务器端的 SessionId 可能存放在很多地方,例如:内存、文件、数据库等。

第一次登录完成之后,后续的访问就可以直接使用 Cookie 进行身份验证了:

1.用户访问A网站的页面b,会带上Cookie信息。

2.服务器验证Cookie中的SessionId和服务器上的是否一致。

3.一致就允许访问,不一致就踢回登录。

存在的问题:

由于服务器端需要对接大量的客户端,也就需要存放大量的 SessionId,这样会导致服务器压力过大。

如果服务器端是一个集群,为了同步登录态,需要将 SessionId 同步到每一台机器上,无形中增加了服务器端维护成本。

由于 SessionId 存放在 Cookie 中,所以无法避免 CSRF 攻击。

2.Token登录

实现流程:

首次登录时:

1.用户访问网站A的页面a,输入密码。

2.服务器验证账号密码,正确则生成token返回给客户端,客户端自行保存。

3.登录成功,允许访问。

后续访问时:

1.用户访问网站A的页面b,请求时传递token,服务端验证token。

2.一致就允许访问,不一致就踢回登录。

特点:

服务器端不需要存放 Token,所以不会对服务器端造成压力,即使是服务器集群,也不需要增加维护成本。

Token 可以存放在前端任何地方,可以不用保存在 Cookie 中,提升了页面的安全性。

Token 下发之后,只要在生效时间之内,就一直有效,如果服务器端想收回此 Token 的权限,并不容易。

Token生成方式:

最常见的 Token 生成方式是使用 JWT(Json Web Token),它是一种简洁的,自包含的方法用于通信双方之间以 JSON 对象的形式安全的传递信息。

使用 Token 后,服务器端并不会存储 Token,那怎么判断客户端发过来的 Token 是合法有效的呢?

答案其实就在 Token 字符串中,其实 Token 并不是一串杂乱无章的字符串,而是通过多种算法拼接组合而成的字符串,我们来具体分析一下。

JWT 算法主要分为 3 个部分:header(头信息),playload(消息体),signature(签名)。

header 部分指定了该 JWT 使用的签名算法:

header = '{"alg":"HS256","typ":"JWT"}' // `HS256` 表示使用了 HMAC-SHA256 来生成签名。

playload 部分表明了 JWT 的意图:

payload = '{"loggedInAs":"admin","iat":1422779638}' //iat 表示令牌生成的时间

signature 部分为 JWT 的签名,主要为了让 JWT 不能被随意篡改,签名的方法分为两个步骤:

1.输入 base64url 编码的 header 部分 、base64url 编码的 playload 部分,输出 unsignedToken。

2.输入服务器端私钥、unsignedToken,输出 signature 签名。

3.SSO 单点登录

实现流程:

单点登录指的是在公司内部搭建一个公共的认证中心,公司下的所有产品的登录都可以在认证中心里完成,一个产品在认证中心登录后,再去访问另一个产品,可以不用再次登录,即可获取登录状态。

首次访问:

1.用户访问网站 a.com 下的 pageA 页面。

2.由于没有登录,则会302重定向到认证中心,并带上回调地址 www.sso.com?return_uri=a.com/pageA,以便登录后直接进入对应页面。

3.用户在认证中心输入账号密码,提交登录。

4.认证中心验证账号密码有效,然后重定向 a.com?ticket=123 带上授权码 ticket,并将认证中心 sso.com 的登录态写入 Cookie。

5.在 a.com 服务器中,拿着 ticket 向认证中心确认,授权码 ticket 真实有效。

6.验证成功后,服务器将登录信息写入 Cookie(此时客户端有 2 个 Cookie 分别存有 a.com 和 sso.com 的登录态)。

认证中心登录完成之后,继续访问 a.com 下的其他页面,由于 a.com 存在已登录的 Cookie 信息,所以服务器端直接认证成功。

再访问 b.com 下的页面:

这个时候,由于认证中心存在之前登录过的 Cookie,所以也不用再次输入账号密码,直接返回第 4 步,下发 ticket 给 b.com 即可。

SSO 单点登录退出:

当某个产品 c.com 退出登录时:

1.清空 c.com 中的登录态 Cookie。

2.请求认证中心 sso.com 中的退出 api。

3.认证中心遍历下发过 ticket 的所有产品,并调用对应的退出 api,完成退出。

4.OAuth 第三方登录

以微信为例:

1.首先,a.com 的运营者需要在微信开放平台注册账号,并向微信申请使用微信登录功能。

2.申请成功后,得到申请的 appid、appsecret。

3.用户在 a.com 上选择使用微信登录。

4.这时会跳转微信的 OAuth 授权登录,并带上 a.com 的回调地址。

5.用户输入微信账号和密码,登录成功后,需要选择具体的授权范围,如:授权用户的头像、昵称等。

6.授权之后,微信会根据拉起 a.com?code=123 ,这时带上了一个临时票据 code。

7.获取 code 之后, a.com 会拿着 code 、appid、appsecret,向微信服务器申请 token,验证成功后,微信会下发一个 token。

8.有了 token 之后, a.com 就可以凭借 token 拿到对应的微信用户头像,用户昵称等信息了。

9.a.com 提示用户登录成功,并将登录状态写入 Cooke,以作为后续访问的凭证。

总结

Cookie + Session 历史悠久,适合于简单的后端架构,需开发人员自己处理好安全问题。Token 方案对后端压力小,适合大型分布式的后端架构,但已分发出去的 token ,如果想收回权限,就不是很方便了。SSO 单点登录,适用于中大型企业,想要统一内部所有产品的登录方式。OAuth 第三方登录,简单易用,对用户和开发者都友好,但第三方平台很多,需要选择合适自己的第三方登录平台。