OAuth2和JWT - 如何设计安全的API?

  • 你已经或者正在实现API;

  • 你正在考虑选择一个合适的方法保证API的安全性;

JWT和OAuth2比较?


要比较JWT和OAuth2?首先要明白一点就是,这两个根本没有可比性,是两个完全不同的东西。

  • JWT是一种认证协议

JWT提供了一种用于发布接入令牌(Access Token),并对发布的签名接入令牌进行验证的方法。令牌(Token)本身包含了一系列声明,应用程序可以根据这些声明限制用户对资源的访问。

  • OAuth2是一种授权框架

另一方面,OAuth2是一种授权框架,提供了一套详细的授权机制(指导)。用户或应用可以通过公开的或私有的设置,授权第三方应用访问特定资源。既然JWT和OAuth2没有可比性,为什么还要把这两个放在一起说呢?实际中确实会有很多人拿JWT和OAuth2作比较。标题里把这两个放在一起,确实有误导的意思。很多情况下,在讨论OAuth2的实现时,会把JSON Web Token作为一种认证机制使用。这也是为什么他们会经常一起出现。

先来搞清楚JWT和OAuth2究竟是干什么的~

JSON Web Token (JWT)


JWT在标准中是这么定义的:

JSON Web Token (JWT) is a compact URL-safe means of representing claims to be transferred between two parties. The claims in a JWT are encoded as a JSON object that is digitally signed using JSON Web Signature (JWS).

-RFC7519 https://tools.ietf.org/html/rfc7519

JWT是一种安全标准。基本思路就是用户提供用户名和密码给认证服务器,服务器验证用户提交信息信息的合法性;如果验证成功,会产生并返回一个Token(令牌),用户可以使用这个token访问服务器上受保护的资源。

一个token的例子:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

一个token包含三部分:

header.claims.signature

了安全的在url中使用,所有部分都 base64 URL-safe进行编码处理。

Header头部分

头部分简单声明了类型(JWT)以及产生签名所使用的算法。

{

“alg” : “AES256”,

“typ” : “JWT”

}

Claims声明

声明部分是整个token的核心,表示要发送的用户详细信息。有些情况下,我们很可能要在一个服务器上实现认证,然后访问另一台服务器上的资源;或者,通过单独的接口来生成token,token被保存在应用程序客户端(比如浏览器)使用。

一个简单的声明(claim)的例子:

{

“sub”: “1234567890”,

“name”: “John Doe”,

“admin”: true

}

Signature签名

签名的目的是为了保证上边两部分信息不被篡改。如果尝试使用Bas64对解码后的token进行修改,签名信息就会失效。一般使用一个私钥(private key)通过特定算法对Header和Claims进行混淆产生签名信息,所以只有原始的token才能于签名信息匹配。

这里有一个重要的实现细节。只有获取了私钥的应用程序(比如服务器端应用)才能完全认证token包含声明信息的合法性。所以,永远不要把私钥信息放在客户端(比如浏览器)。

OAuth2是什么?


相反,OAuth2不是一个标准协议,而是一个安全的授权框架。它详细描述了系统中不同角色、用户、服务前端应用(比如API),以及客户端(比如网站或移动App)之间怎么实现相互认证。

The OAuth 2.0 authorization framework enables a third-party application to obtain limited access to an HTTP service, either on behalf of a resource owner by orchestrating an approval interaction between the resource owner and the HTTP service, or by allowing the third-party application to obtain access on its own behalf.

-RFC6749 https://tools.ietf.org/html/rfc6749

这里简单说一下涉及到的基本概念。

Roles角色

应用程序或者用户都可以是下边的任何一种角色:

  • 资源拥有者

  • 资源服务器

  • 客户端应用

  • 认证服务器

Client Types客户端类型

这里的客户端主要指API的使用者。它可以是的类型:

  • 私有的

  • 公开的

Client Profile客户端描述

OAuth2框架也指定了集中客户端描述,用来表示应用程序的类型:

  • Web应用

  • 用户代理

  • 原声应用

Authorization Grants认证授权

认证授权代表资源拥有者授权给客户端应用程序的一组权限,可以是下边几种形式:

  • 授权码

  • 隐式授权

  • 资源拥有者密码证书

  • 客户端证书

  • Endpoints终端

OAuth2框架需要下边几种终端:

  • 认证终端

  • Token终端

  • 重定向终端

从上边这些应该可以看出,OAuth2定义了一组相当复杂的规范。

使用HTTPS保护用户密码

在进一步讨论OAuth2和JWT的实现之前,有必要说一下,两种方案都需要SSL安全保护,也就是对要传输的数据进行加密编码。

安全地传输用户提供的私密信息,在任何一个安全的系统里都是必要的。否则任何人都可以通过侵入私人wifi,在用户登录的时候窃取用户的用户名和密码等信息。

一些重要的实施考虑

在做选择之前,参考一下下边提到的几点。

时间投入

OAuth2是一个安全框架,描述了在各种不同场景下,多个应用之间的授权问题。有海量的资料需要学习,要完全理解需要花费大量时间。甚至对于一些有经验的开发工程师来说,也会需要大概一个月的时间来深入理解OAuth2。这是个很大的时间投入。

相反,JWT是一个相对轻量级的概念。可能花一天时间深入学习一下标准规范,就可以很容易地开始具体实施。

出现错误的风险

OAuth2不像JWT一样是一个严格的标准协议,因此在实施过程中更容易出错。尽管有很多现有的库,但是每个库的成熟度也不尽相同,同样很容易引入各种错误。在常用的库中也很容易发现一些安全漏洞。

当然,如果有相当成熟、强大的开发团队来持续OAuth2实施和维护,可以一定成都上避免这些风险。

社交登录的好处

在很多情况下,使用用户在大型社交网站的已有账户来认证会方便。

如果期望你的用户可以直接使用Facebook或者Gmail之类的账户,使用现有的库会方便得多。

结论


做结论前,我们先来列举一下  JWT和OAuth2的主要使用场景。

JWT使用场景
无状态的分布式API

JWT的主要优势在于使用无状态、可扩展的方式处理应用中的用户会话。服务端可以通过内嵌的声明信息,很容易地获取用户的会话信息,而不需要去访问用户或会话的数据库。在一个分布式的面向服务的框架中,这一点非常有用。

但是,如果系统中需要使用黑名单实现长期有效的token刷新机制,这种无状态的优势就不明显了。

优势

  • 快速开发

  • 不需要cookie

  • JSON在移动端的广泛应用

  • 不依赖于社交登录

  • 相对简单的概念理解

限制

  • Token有长度限制

  • Token不能撤销

  • 需要token有失效时间限制(exp)

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
(img-ekE2JrzJ-1715863058260)]

[外链图片转存中…(img-1yCoHXQg-1715863058260)]

[外链图片转存中…(img-9IeXltga-1715863058260)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

  • 7
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值