前端网络高级篇(二)身份认证

网络身份的验证的场景非常普遍,比如用户登陆后才有权限访问某些页面或接口。而HTTP通信是无状态的,无法记录用户的登陆状态,那么,如何做身份验证呢?

下面,会从浅入深,陆续介绍几种常用的认证方式和相关概念。文章较长,请耐心阅读。

1. 鉴权与授权

  • 鉴权 Authentication,指对于一个声明者所声明的身份权利,对其所声明的真实性进行鉴别确认的过程。
    例子:用户名张三,密码******,用户名和密码通过挖财验证,登陆成功
  • 授权 Authorization,一般是指获取用户的委派权限。
    例子:我是张三,有权访问git/client/jizhang,因为gitlab给我进行了授权
image

一般流程为先鉴权再授权。而身份验证指的就是鉴权这个步骤。

1.2 常用的鉴权方式

  • 方式一:HTTP Basic Authentication (401)
    客户端发送http request 给服务器,服务器验证该用户是否已经登录验证过了,如果没有的话,服务器会返回一个401 Unauthozied给客户端,并且在Response 的 header “WWW-Authenticate” 中添加信息。
    然后,浏览器弹出输入框要求输入用户名和密码。

    image

    用户输入正确的用户名和密码后,浏览器用BASE64编码,放在Authorization header中发送给服务器。如下图:
    image

    最后,服务器将Authorization header中的用户名密码取出,进行验证, 如果验证通过,将根据请求,发送资源给客户端。

  • 方式二:Session-cookie

  • 方式三:Token

  • 方式四:OAuth(开发授权)

后三种验证方式下面逐渐展开讲解。

2. Token VS Cookies

image

2.1 Cookies

Cookies是传统的鉴权方式,通过浏览器携带的Cookies字段来进行状态存储。特点如下:

  • 认证信息在服务端需要存储。cookies携带sessionId,用户经过认证之后,应用都要在服务端做一次记录,以方便用户下次请求的鉴别。session的保存方法多种多样,可以保存在文件中,也可以内存里,或第三方媒介,比如redis或者mongodb。随着认证用户的增多,服务端的开销会明显增大。缺点
  • 一般不需要客户端存储。服务端通过reponse: Set-Cookie头信息为客户端设置cookie,客户端不需要做特殊配置,浏览器会在后续的ajax请求中自动带上cookie。
    image
  • 有CSRF(跨站点伪造请求)风险。缺点
  • 移动端用在使用cookie时有各种不便利和局限。缺点
  • Cookie可以在同一域名下或者同一主域不同子域下共享,一旦跨主域,就无法共享缺点
  • 分布式应用上,可能会限制负载均衡器的能力。用户认证之后,服务端做认证记录,如果认证的记录被保存在内存中的话,这意味着用户下次请求还必须要请求在这台服务器上,这样才能拿到授权的资源,这样在分布式的应用上,相应的限制了负载均衡器的能力。这也意味着限制了应用的扩展能力。缺点

2.2 Token

Token是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个Token便将此Token返回给客户端,以后客户端只需带上这个Token前来请求数据即可,无需再次带上用户名和密码。

最简单的token组成:uid(用户唯一的身份标识)、time(当前时间的时间戳)、sign(签名,由token的前几位+盐以哈希算法压缩成一定长的十六进制字符串,可以防止恶意第三方拼接token请求服务器)。

相比Cookies,Token的优势明显多了。

  • 服务端无需存储认证信息。因为Token本身就存储了认证信息。
  • 需要前端存储(建议用localstorage)。客户端通过request: Authorization头信息设置Token,发给服务端做验证。缺点
    image
  • 无CSRF风险
  • 适合移动端身份认证
  • token支持各类跨域

Javascript支持Token如下:

// JS
var res = new XMLHttpRequest();
...
req.setRequestHeader('Authorization',accesstoken);
  
// JQuery
$.ajax({
   url: api,
   type: "GET",
   headers: { "Authorization": "Bearer " + token}
})

2.3 什么是JWT(Json web token)

JWT是实现Web应用会话管理的一种方式。广义上来讲,它是一种开发标准,而非技术实现(大部分的语言平台都有按照它规定的内容提供了自己的技术实现);狭义上讲,它就是用来传递的Token字符串。

看一下JWT是如何传递的。


image

它长得像下面这样。。。


image

JWT是如何对信息签名加密的呢?
要前面的信息分为三部分:header,payload和signature。

  • header:说明这个JWT签发的时候所使用的签名和摘要算法
{
  "typ": "JWT",
  "alg": "HS256"
}
  • payload:用来承载要传递的数据
{
  "sub": "1234567890",
  "name": "john Doe",
  "admin": true
}
  • signature:密钥

签名过程:把headerpayload对应的json结构进行base64url编码之后得到的两个串用英文句点号拼接起来,然后根据header里面alg指定的签名算法生成出来的。函数如下:

HMACSH256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret
)

image

HMAC计算:https://1024tools.com/hmac

下面的内容都是基于Token认证

3. Token有效期

显而易见,身份验证必须要有有效期!那么,如何在”用户无感知”的情况下处理Token失效?

  • 方案一: 服务器端保存 Token 状态,用户每次操作都会自动刷新(推迟) Token 的过期时间。
    • 缺点:请求次数多时,每次都刷新过期时间代价较大
  • 方案二:refresh token
    • 优点:服务端不需要刷新token,避免频繁读写操作

那让我们看看什么是refresh token?

3.1 Refresh token

第一步,登陆。


image

第二步,业务请求


image

第三步,Token过期,刷新Token


image

那么,如果refresh token也过期呢?好吧,请重新登陆吧。

3.2 Refresh token自动续期

可以在Refresh token每次使用时,更新它的过期时间。也可以在创建Refresh token时,就指定它的过期时间,比如,距离创建时间XXX天后过期。

看到这里,大家应该觉得身份验证可以完美收官了。。。但是,前面所讲的技术都有一个大前提,就是,认证服务和业务服务在一起的。
比如,上淘宝网,用淘宝账号登陆,没有问题。
但是,现在很多网站都没有自己的账号密码,而是通过第三方账号登陆,比如微信,微博,QQ。

这种认证服务和业务服务分离的情况下,如何做身份认证呢?继续下面两节吧!

4. 分离认证服务

认证服务和业务服务分离时,利用Token的无状态特性,实现单点登陆。

第一步,登录和业务请求


image

第二步,更新Token

image

这样好像完美多了。但是,又有个问题,上图是在认证服务器信任业务服务器的场景下工作的。

问题1:如何处理不受信任的业务服务器呢?
答案:使用非对称加密签名,认证服务器使用密钥A签发(私钥),业务服务器使用密钥B验证(公钥)。

问题2: 多个业务服务器之间使用相同的Token对用户来说是不安全的!!!任何一个服务器拿到Token都可以仿冒用户去另一个服务器处理业务,怎么处理?
答案:认证服务器产生Token时,需要把使用方-业务服务器相关信息记录在Token中。

问题3:如果用户不信任业务服务器呢?
答案:让『认证服务』帮助用户甄别『业务服务』!

开发式API可以解决上面的所有问题。

5. 开放式API - OAuth

OAuth 2.0是一个关于授权(authorization)的开放网络标准。

image

认证服务器不公开公钥, 业务服务需要在认证服务注册,通过审核,拿到特定公钥。
然后,用户通过认证服务器授权,将授权数据加密到Token中。

OAuth有四个角色:

  • 资源拥有者(Resource Owner) - 用户
  • 客户端(Client) - 三方应用
  • 资源服务器(Resource Server) - 存放用户资源和信息
  • 授权服务器(Authorization Server) - 给三方颁发授权令牌(access token)

授权流程如下图:


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