前端登录,这一篇就够了

登录是每个网站中都经常用到的一个功能,在页面上我们输入账号密码,敲一下回车键,就登录了,但这背后的登录原理你是否清楚呢?今天我们就来介绍几种常用的登录方式。

Cookie + Session 登录

Token 登录

SSO 单点登录

OAuth 第三方登录

Cookie + Session 登录

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

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

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

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

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

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

Cookie + Session  实现流程

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

用户首次登录时:

首次登陆

用户访问 a.com/pageA,并输入密码登录。

服务器验证密码无误后,会创建 SessionId,并将它保存起来。

服务器端响应这个 HTTP 请求,并通过 Set-Cookie 头信息,将 SessionId 写入 Cookie 中。

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

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

后续访问

用户访问 a.com/pageB 页面时,会自动带上第一次登录时写入的 Cookie。

服务器端比对 Cookie 中的 SessionId 和保存在服务器端的 SessionId 是否一致。

如果一致,则身份验证成功。

Cookie + Session  存在的问题

虽然我们使用 Cookie + Session  的方式完成了登录验证,但仍然存在一些问题:

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

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

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

Token 登录

为了解决 Session + Cookie 机制暴露出的诸多问题,我们可以使用 Token 的登录方式。

Token 是服务端生成的一串字符串,以作为客户端请求的一个令牌。当第一次登录后,服务器会生成一个 Token 并返回给客户端,客户端后续访问时,只需带上这个 Token 即可完成身份认证。

Token 机制实现流程

用户首次登录时:

用户输入账号密码,并点击登录。

服务器端验证账号密码无误,创建 Token。

服务器端将 Token 返回给客户端,由***客户端自由保存***。

后续页面访问时:

用户访问 a.com/pageB 时,带上第一次登录时获取的 Token。

服务器端验证 Token ,有效则身份验证成功。

Token 机制的特点

根据上面的案例,我们可以分析出 Token 的优缺点:

服务器端不需要存放 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 不能被随意篡改,签名的方法分为两个步骤:

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

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

const base64Header = encodeBase64(header)

const base64Payload = encodeBase64(payload)

const unsignedToken = `${base64Header}.${base64Payload}`

const key ='服务器私钥'

signature = HMAC(key, unsignedToken)

最后的 Token 计算如下:

const base64Header = encodeBase64(header)

const base64Payload = encodeBase64(payload)

const base64Signature = encodeBase64(signature)

token = `${base64Header}.${base64Payload}.${base64Signature}`

服务器在判断 Token 时:

const [base64Header, base64Payload, base64Signature] = token.split('.')

const signature1 = decodeBase64(base64Signature)

const unsignedToken = `${base64Header}.${base64Payload}`

const signature2 = HMAC('服务器私钥', unsignedToken)

if(signature1 === signature2) {

return'签名验证成功,token 没有被篡改'

}

const payload =  decodeBase64(base64Payload)

if(new Date() - payload.iat <'token 有效期'){

return'token 有效'

}

有了 Token 之后,登录方式已经变得非常高效,接下来我们介绍另外两种登录方式。

SSO 单点登录

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

SSO 机制实现流程

用户首次访问时,需要在认证中心登录:

SSO流程

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

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

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

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

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

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

认证中心登录完成之后,继续访问 a.com 下的其他页面:

这个时候,由于 a.com 存在已登录的 Cookie 信息,所以服务器端直接认证成功。

如果认证中心登录完成之后,访问 b.com 下的页面:

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

SSO 单点登录退出

目前我们已经完成了单点登录,在同一套认证中心的管理下,多个产品可以共享登录态。现在我们需要考虑退出了,即:在一个产品中退出了登录,怎么让其他的产品也都退出登录?

原理其实不难,可以回过头来看第 5 步,每一个产品在向认证中心验证 ticket 时,其实可以顺带将自己的退出登录 api 发送到认证中心。

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

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

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

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

OAuth 第三方登录

在上文中,我们使用单点登录完成了多产品的登录态共享,但都是建立在一套统一的认证中心下,对于一些小型企业,未免太麻烦,有没有一种登录能够做到开箱即用?

其实是有的,很多大厂都会提供自己的第三方登录服务,我们一起来分析一下。

OAuth 机制实现流程

这里以微信开放平台的接入流程为例:

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

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

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

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

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

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

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

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

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

总结

本文介绍了 4 种常见的登录方式,原理应该大家都清楚了,总结一下这 4 种方案的使用场景:

Cookie + Session 历史悠久,适合于简单的后端架构,需开发人员自己处理好安全问题。

Token 方案对后端压力小,适合大型分布式的后端架构,但已分发出去的 token ,如果想收回权限,就不是很方便了。

SSO 单点登录,适用于中大型企业,想要统一内部所有产品的登录方式。

OAuth 第三方登录,简单易用,对用户和开发者都友好,但第三方平台很多,需要选择合适自己的第三方登录平台。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,948评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,371评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,490评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,521评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,627评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,842评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,997评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,741评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,203评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,534评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,673评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,339评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,955评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,770评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,000评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,394评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,562评论 2 349