互联网概念的token认证,大抵是在RESTful API 流行后提出的,在开始token认证之前,我们先梳理下常见的互联网认证机制。

一、HTTP Basic Auth

HTTP Basic Auth常见的有两种:第一种就是最常见的,即我们在登陆一些web页面时,会让我们输入用户名密码;另一种是将用户名密码信息通过base64这类算法变换成一条字符串在http请求头中增加auth字段,再传输给服务端。

这个属于最原始级的认证,缺点比较明显,存在http头中的密码信息容易被抓包获取,用户名密码后服务端后需要查询数据库里的信息,进行比对信息,这也增加了服务器的负担。

二、session+cookie模式

假设目前我们有一个查询类的web站点,不可能查询都要登陆一次,为解决一次登陆,可以在固定一段时间内都免登陆查询,就出现了session+cookie模式,该模式是第一次登陆时使用HTTP Basic Auth,认证成功后,为避免每次都到数据库里校验用户名密码信息,就在主机上存储一份登陆的session信息,在本身cookie里记录对应的session信息,cookie里同时保存expire time。

该模式优缺点都比较明显:session信息需要额外的数据库存储,例如一般需增加redis、memached等应用。在多机负载时,需要考虑session共享;但好处也是明显的,session信息统一管理,可以在服务端统一控制认证的过期时间或个别用户的过期时间。

三、简单token认证

token认证最常用的应用场景就是查询接口的调用(RESTful API),查询接口的信息在没有安全需求时,大家都可以通过get方法或post方法取得所需信息。但在有安全需要时一般需要认证后才能获取所需的信息,这时候可以通过先能过HTTP Basic Auth,HTTP Basic Auth认证完成后,服务端返回给客户端一个类似于UUID的唯一标识,我们称之为token。该token一般可以在URL或head头里加入,如以下的常见的URL模式

http://api,361way.com/getinfo?token=xxxxx 或 http://api,361way.com/getinfo?t=xxxxx ,后面再加上相应的查询信息,就可以获取到相应的数据。

token的好处是服务端不需要存储相应信息,但被不怀好意的人从中间获取到该信息时,也容易被利用,非法获取数据。

由于这个简单的token返回串里未返回相应的过期时间信息,如果想增强安全性,一般可以在服务端生成时配合时间戳生成,服务端在接收到client发来带token的信息时,先检测反解token获取时间戳信息,如果该时间戳在超过某个时间点时,就认为过期,需要重新获取。

四、OAuth认证

OAuth(开放授权)是一个开放的授权标准,允许用户让第三方应用访问该用户在某一web服务上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用。OAuth允许用户提供一个令牌,而不是用户名和密码来访问他们存放在特定服务提供者的数据。每一个令牌授权一个特定的第三方系统(例如,视频编辑网站)在特定的时段(例如,接下来的2小时内)内访问特定的资源(例如仅仅是某一相册中的视频)。这样,OAuth让用户可以授权第三方网站访问他们存储在另外服务提供者的某些特定信息,而非所有内容。

这个理解起来比较绕口,举个例子,如很多网站上面有qq或微信登陆接口,qq或微信提供的就是OAuth认证。OAuth虽然名字很洋气,其本质还是token认证,仔细研究下上面的话,是不是原理上和上面提到的简单token认证类似,只不过其加了几个callback函数而已
这里以douban豆瓣网调用QQ的OAuth节口为例,其调用方式如下:

# 发起认证:
http://www.douban.com/leadToAuthorize
# 重定向到QQ认证,并指定回调:
http://www.qq.com/authorize?callback=www.douban.com/callback
# 返回授权码,并callback到douban
http://www.douban.com/callback
五、JWT认证

JSON Web Token(JWT)是一个非常轻巧的规范。这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息。一个JWT实际上就是一个字符串,它由三部分组成,头部(Header)、载荷(Payload)与签名(Signature)。这里只简单说下理论,会另开博文深层讨论。

Payload里存放的是存储签发者、签发时间、过期时间、一些数据信息的JSON格式的内容。

{ "iss": "Online JWT Builder",
"iat": 1416797419,
"exp": 1448333419,
"aud": "www.example.com",
"sub": "jrocket@example.com",
"GivenName": "Johnny",
"Surname": "Rocket",
"Email": "jrocket@example.com",
"Role": [ "Manager", "Project Administrator" ]
}

Header里指定存放的是指定使用的协议JWT、加密签名的类型,示例如下:

{
"typ": "JWT",
"alg": "HS256"
}

最后签名就是将上面两者的信息通过BASE64编码,再加上密钥信息,三者之间通过点号连接,就组合成的JWT token。可以对比简单token和JWT的区别,两者本质上都是token,只不过JWT在token里多传输了一些信息。

原文来自:http://www.361way.com/token-auth/5844.html

本文地址:https://www.linuxprobe.com/talk-token-auth.html编辑:张雄,审核员:逄增宝