使用JWT来保证API安全

JWT

why JWT

现在,前后端分离和 RESTful API 越来越火热,当后台渐渐开始只负责为客户端提供 API 接口之后,身份校验和接口安全成了难题。在传统的开发模式下,使用 cookie-session 可以保证接口安全,在没有登录的情况下访问关键数据会跳转到登录界面或者请求失败。而使用 REStful API 之后,cookie-session 存在以下 3 个问题:

  • 客户端除了浏览器,可能还包括手机端 APP,对于手机端而言,管理 cookie 是一件麻烦的事情。
  • RESTful 风格的 API 不建议使用 cookie。
  • cookie 本身有一个缺陷,不能跨域。

正是存在上面的几个缺陷,现在 API 开始使用 JWT 代替 cookie-session 来做身份验证。

what JWT

JWT 全称 JSON Web Token。本质上 JWT 是一串 token 字符串。客户端登录之后,服务端返回一串 token 给客户端,之后每次客户端请求 API 接口都需要携带该 token 进行身份校验。JWT 由三个部分组成:头部(header)、载荷(payload)、签名(signature)。这三个部分使用 . 连接在一起就是一个完整的 JWT。所以,一个完整的 JWT 应该类似下面这种形式:

xxxxxx.yyyyy.zzzzz

header

header 是一个 json 数据,用于描述 JWT 的基本信息。一般要由两个部分组成:

  • alg
  • typ

alg 代表的是加密所使用的算法(后面会提到加密数据),typ 表示该 token 是什么类型的。这里 typ 自然是 JWT。

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

一个完整的 header 信息。最后使用 Base64 对 header 进行编码,得到 JWT 的第一部分。

payload

payload 是 JWT 存储信息的部分。payload 也是一个 json 数据,每一个 json 的 key-value 称为一个声明。

payload 有两种类型的声明:标准声明和自定义声明。

标准声明一共有 6 个,其名称和对应含义如下:

  • iss : JWT 的签发者。
  • iat : JWT 的签发时间,是一个 unix 时间戳。
  • exp : JWT 的过期时间,是一个 unxi 时间戳。
  • aud : 接受 JWT 的一方。
  • sub : JWT 所面向的用户。
  • jti : 唯一标识一个 JWT。

自定义声明为用户自己定义的 key-value,可以用来存储一些简单的基本信息。考虑到性能,不应该在 payload 中定义太多自定义声明。

定义一个 payload :

{
    "iss": "jaychen",
    "iat": 1441593502,
    "exp": 1441594722,
    "aud": "jaychen.cc",
    "sub": "chenjiayaooo@gmail.com",
    "jti:" "xxxxxxxx",

    "user_id": "1",
    "username": "jaychen"
}

上面这个 payload 中,idusername 为自定义声明。

有了 payload 只有,将该 payload 进行 Base64 加密,得到一串字符串之后,用 . 把 header 和 payload 连接起来。

signature

将 header 和 payload 两个部分连接起来之后,得到的字符串类似下面

xxxxx.yyyyy

接着,使用 header.alg 定义的加密算法对 hader.payload 的字符串进行加密,并且加密的时候应该有一个密钥。加密之后,得到一串加密字符串,最后把这串加密字符串也是用 . 拼接在 header.payload 后面,形成完整的 JWT。

这里签名的目的是为了保证 payload 数据的完整性。如果 JWT 在传输过程中被第三方劫持,中间人对 header.payload 进行修改,并且使用自己的密钥重新签名。服务端收到中间人修改过的 JWT,使用自己的密钥对 header.payload 进行再次加密,由于中间人和服务端使用的是不同的密钥签名,所以服务端再次加密的结果肯定和中间人加密的结果不一致,由此可以断定该 JWT 被恶意篡改。

基于 JWT 的身份验证

现在已经明白了 JWT 的生成过程,现在来梳理下 JWT 的使用流程。

  • 首次登陆系统,向服务端发送 username&&password 进行登录。
  • 服务端验证 username&&password,验证合法为客户端生成一串 JWT,这里在 payload 中可以自定义声明 user_id,username 等字段用来保存信息。
  • 客户端收到服务端的 JWT 字符串,自行保存。后续需要请求 API 都要携带该 JWT 到服务端进行身份校验。
  • 服务端收到客户端的 API 请求,先获取 JWT 信息,通过签名判断 JWT 的合法性,如果合法,返回数据。

JWT 的优点和注意事项

注意事项

上面生成 JWT 的过程中使用了 Base64 的加密算法对 payload 进行加密,Base64 是一种可逆的加密算法,这意味着其他人可以轻易的从加密结果中得到加密之前的信息,所以这注定了 payload 中不能保存密码之类的敏感信息。

优点

回顾上面生成 JWT 的步骤,payload 中我们保存了 user_idusername 这样的信息。在传统的 cookie-session 中,这些数据是服务端在 session 中维护的。JWT 把之前需要在服务端维护的 session 数据转移到客户端,使得服务端的压力小了很多。

JWT 本质只是一串字符串,所以可以无限制的使用各种姿势传递给服务端:当做 get 参数拼接在 URL 中、添加到 header 头部中、当做 post 参数传递。。。

如果客户端是手机 APP 等非浏览器客户端,那么使用 JWT 就可以免去对 cookie 的管理。

本文首发于:https://jaychen.cc
作者:jaychen

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

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,497评论 18 139
  • 转载本文需注明出处:微信公众号EAWorld,违者必究。 本文目录: 一、单体应用 VS 微服务 二、微服务常见安...
    72a1f772fe47阅读 8,523评论 3 25
  • 本文目录:一、单体应用 VS 微服务二、微服务常见安全认证方案三、JWT介绍四、OAuth 2.0 介绍五、思考总...
    挨踢的懒猫阅读 17,926评论 5 29
  • 摘要: 在Web应用中,使用JWT替代session并不是个好主意 适合JWT的使用场景 抱歉,当了回标题党。我并...
    ThoughtWorks阅读 276,461评论 157 388
  • 1. 微服务架构介绍 1.1 什么是微服务架构? 形像一点来说,微服务架构就像搭积木,每个微服务都是一个零件,并使...
    静修佛缘阅读 6,609评论 0 39