文章目录

  • 【如何设计安全可靠的开放接口】系列
  • 前言
    • 一、Token机制
      • 1. Token生成
      • 2. Session存在的问题
      • 3. JWT是如何解决Session存在的问题的
    • 二、JWT中的数据结构
      • 1. Header
      • 2. Payload
      • 3. Signature
    • 三、JWT的工作方式
    • 四、JWT的使用
      • 1. 生成Token
      • 2. token验证
      • 3. token解析
      • 4. 带过期时间的Token

【如何设计安全可靠的开放接口】系列

1. 如何设计安全可靠的开放接口—之Token
2. 如何设计安全可靠的开放接口—之AppId、AppSecret
3. 如何设计安全可靠的开放接口—之签名(sign)
4. 如何设计安全可靠的开放接口【番外篇】—关于MD5应用的介绍
5. 如何设计安全可靠的开放接口—还有哪些安全保护措施
6. 如何设计安全可靠的开放接口—对请求参加密保护
7. 如何设计安全可靠的开放接口【番外篇】— 对称加密算法

前言

Open API是会暴露到公网被访问的接口,那与内网接口最重要的区别就是如何做好安全的问题,常见的安全问题有:合法身份判别、数据防窥、数据防篡改、请求防重放、Dos攻击等等,本文先来看看对于合法身份判别这个问题是如何解决的。

一、Token机制

Token自然是非常好的选择,客户端成功登陆后,服务端就会生成一个Token返回给客户端,之后客户端每次请求只需要带上这个Token即可表明身份,解决了每次登陆的问题(Http是无状态通信协议)。

1. Token生成

关于Token的生成最常见的方式就是使用JWT(JSON Web Token),早期要说解决每次登陆的问题,通过Session就可以做到,那为什么又出现了JWT呢?

我们先来看看使用Session实现的方式

  1. 用户在客户端输入账号、密码。
  2. 服务端验证账号、密码正确后,获取当前session,并在session里面保存需要的数据。
  3. 服务器像客户端返回一个session_id,并将此写入客户端Cookie中。
  4. 之后用户每次在客户端的请求都会从Cookie中把session_id带给服务端。
  5. 服务端只需要根据session_id匹配到之前保存在session里面的数据即可。

2. Session存在的问题

session这种方式最大的问题就是需要服务端保存数据,如果要做跨域访问、集群访问就需要每台服务器都能同步到session信息,当然你可以通过一些分布式的组件来持久化session,但在跨域访问中依然比较棘手,而且代价也较高。

3. JWT是如何解决Session存在的问题的

既然服务端保存session必然存在数据同步的问题,那就干脆不要保存了,这就是JWT的做法,数据只会记录在客户端,当验证完用户的账号、密码后,JWT会生成一种约定好的格式数据,然后服务端把这份数据发送给客户端,客户端之后每次请求带上这份数据即可,JWT自然能够对其进行验证,这样一来,服务端就从有状态变成无状态了,也就能轻松的实现扩展了。

二、JWT中的数据结构

JWT中的数据主要由三部分组成,分别是Header、Payload、Signature

原始数据

加密后

三部分数据用'.'隔开

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoieGlhb21pbmciLCJpZCI6MTIzNDUsImV4cCI6MTY1MjA5ODczNX0.7WRvMdrILoSkic1uUhg34Xj31XI0ok4Lrd6qEC99Abg

1. Header

Header通常由两部分组成,例如:

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

"typ": "JWT"令牌类型,即JWT。
"alg": "HS256"使用的签名算法。

2. Payload

Payload是用来存放实际需要保存数据的地方,其中JWT官方也定义了一些字段


这些字段并不是强制性的,官方只是建议使用,当然你也可以自己定义各种字段,但一定要注意命名规范,避免冲突。

需要额外注意的是,保存在Payload中的信息默认是没有加密的,前面看到的数据只是签名后的结果,签名只能防止数据被篡改,所以,除非是做了二次加密,否则就不能把隐私信息放到Head或者Payload中。

3. Signature

Signature是对前面两部分数据的签名,用于验证数据没有被篡改,签名后的数据就变成如下这样:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoieGlhb21pbmciLCJpZCI6MTIzNDUsImV4cCI6MTY1MjA5ODczNX0.7WRvMdrILoSkic1uUhg34Xj31XI0ok4Lrd6qEC99Abg

三、JWT的工作方式

服务端生成Token后,一般可以保存在HTTP的请求头的Authorization字段中

四、JWT的使用

引入jar包

<dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>3.19.2</version>
</dependency>

1. 生成Token

public static void main(String[] args) {String token = createToken();System.out.println(token);
}private static String createToken() {try {Algorithm algorithm = Algorithm.HMAC256("secret");return JWT.create().withIssuer("admin").withClaim("name", "xiaozhang").withClaim("id", 12345).sign(algorithm);} catch (JWTCreationException e) {e.printStackTrace();}return null;
}

2. token验证

public static boolean verifyToken(String token) {try {Algorithm algorithm = Algorithm.HMAC256("secret"); //use more secure keyJWTVerifier verifier = JWT.require(algorithm).withIssuer("admin").withClaim("name", "xiaozhang").withClaim("id", 123456) // 把id由原来的12345修改为123456.build();verifier.verify(token);} catch (JWTVerificationException e) {e.printStackTrace();return false;}return true;
}
com.auth0.jwt.exceptions.InvalidClaimException: The Claim 'id' value doesn't match the required one.at com.auth0.jwt.JWTVerifier.assertValidClaim(JWTVerifier.java:397)at com.auth0.jwt.JWTVerifier.verifyClaimValues(JWTVerifier.java:349)at com.auth0.jwt.JWTVerifier.verifyClaims(JWTVerifier.java:315)at com.auth0.jwt.JWTVerifier.verify(JWTVerifier.java:300)at com.auth0.jwt.JWTVerifier.verify(JWTVerifier.java:283)at token.TokenDemo.verifyToken(TokenDemo.java:28)at token.TokenDemo.main(TokenDemo.java:16)
false

3. token解析

private static Map<String, Claim> decodeToken(String token) {DecodedJWT jwt = JWT.decode(token);return jwt.getClaims();
}
{iss="admin", name="xiaozhang", id=12345}

4. 带过期时间的Token

LocalDateTime plus = LocalDateTime.now().plus(3, ChronoUnit.SECONDS);
Date expiresAt = Date.from(plus.atZone(ZoneId.systemDefault()).toInstant());
System.out.println("expiresAt: " + expiresAt);
String expiresToken = createToken(expiresAt);
Thread.sleep(4000);
System.out.println("expiresToken: " + verifyToken(expiresToken));
private static String createToken(Date expiresAt) {try {Algorithm algorithm = Algorithm.HMAC256("secretreturn JWT.create().withIssuer("admin").withClaim("name", "xiaozhang").withExpiresAt(expiresAt).withClaim("id", 12345).sign(algorithm);} catch (JWTCreationException e) {e.printStackTrace();}return null;
}
expiresAt: Mon May 09 20:52:20 CST 2022
com.auth0.jwt.exceptions.TokenExpiredException: The Token has expired on Mon May 09 20:52:20 CST 2022.at com.auth0.jwt.JWTVerifier.assertDateIsFuture(JWTVerifier.java:420)at com.auth0.jwt.JWTVerifier.assertValidDateClaim(JWTVerifier.java:411)at com.auth0.jwt.JWTVerifier.verifyClaimValues(JWTVerifier.java:331)at com.auth0.jwt.JWTVerifier.verifyClaims(JWTVerifier.java:315)at com.auth0.jwt.JWTVerifier.verify(JWTVerifier.java:300)at com.auth0.jwt.JWTVerifier.verify(JWTVerifier.java:283)at token.TokenDemo.verifyToken(TokenDemo.java:72)at token.TokenDemo.main(TokenDemo.java:39)
expiresToken: false

如何设计安全可靠的开放接口---之Token相关推荐

  1. 如何设计安全可靠的开放接口---之AppId、AppSecret

    文章目录 [如何设计安全可靠的开放接口]系列 前言 AppId的使用 AppId的生成 AppSecret生成 总结 [如何设计安全可靠的开放接口]系列 1. 如何设计安全可靠的开放接口-之Token ...

  2. 如何设计安全可靠的开放接口---对请求参加密保护

    文章目录 [如何设计安全可靠的开放接口]系列 前言 AES加解密 代码实现 [如何设计安全可靠的开放接口]系列 1. 如何设计安全可靠的开放接口-之Token 2. 如何设计安全可靠的开放接口-之Ap ...

  3. 如何设计安全可靠的开放接口---之签名(sign)

    文章目录 [如何设计安全可靠的开放接口]系列 前言 一.前置知识 二.签名的作用 1. 数据防篡改 2. 身份防冒充 三.流程说明 前置准备 交互流程 接口请求方 接口提供方 完整代码补充 总结 [如 ...

  4. App开放接口api安全:Token签名sign的设计与实现

    点击上方蓝色"方志朋",选择"设为星标"回复"666"获取独家整理的学习资料! 来源:cnblogs.com/whcghost/p/5657 ...

  5. python api接口 安全_App开放接口api安全性的设计与实现

    前言 在app开放接口api的设计中,避免不了的就是安全性问题,因为大多数接口涉及到用户的个人信息以及一些敏感的数据,所以对这些接口需要进行身份的认证, 那么这就需要用户提供一些信息,比如用户名密码等 ...

  6. 魔高一丈道高一尺,开放接口安全性设计

    2019独角兽企业重金招聘Python工程师标准>>> 乐猿社区,程序员的花果山 问题 在开放接口api的设计中,避免不了的就是安全性问题,因为大多数接口涉及到用户的个人信息以及一些 ...

  7. 开放接口/RESTful/Api服务的设计和安全方案详解

    一.总体思路 这个涉及到两个方面问题: 一个是接口访问认证问题,主要解决谁可以使用接口(用户登录验证.来路验证) 一个是数据数据传输安全,主要解决接口数据被监听(HTTPS安全传输.敏感内容加密.数字 ...

  8. API 开放接口设计之 appId,appSecret,accessToken (同微信开发平台接口)

    前篇:如何设计开放 Api 以下链接来源于网络素材: 需要考虑点摘录一: https://blog.csdn.net/weixin_34414196/article/details/92105613 ...

  9. 如何设计和搭建一个开放平台,提供开放接口?12张PPT给你答案

    如何设计和搭建一个开放平台,提供开放接口?12张PPT给你答案 (作者:dogstar) 1.未来趋势会如何? 随着互联网技术的发展,现在已经是到达了信息化爆炸的时代,并且各种技术层出不穷.比起十多年 ...

最新文章

  1. 数组遍历——Vue.js
  2. 从零开始打造自己的PHP框架――第2章
  3. python爬取淘宝商品做数据挖掘_Python 3爬虫 数据清洗与可视化实战 Python数据抓取技术 python3网络爬虫教程书籍 运用Python工具获取电商平台页面数据挖掘书籍...
  4. 数学之美 系列八-- 贾里尼克的故事和现代语言处理
  5. Sqoop(四)增量导入、全量导入、减量导入
  6. 《OD大数据实战》MongoDB环境搭建
  7. 监控mysql锁定状态_企业实战Mysql不停机维护主从同步
  8. 百度音乐 android,千千音乐(com.ting.mp3.android) - 8.2.3.4 - 应用 - 酷安
  9. CATransform3D 特效详解
  10. Visual Studio 2015编译wxWidgets
  11. Android Intent机制与常见的用法
  12. 独热向量编码(one-hot encoding)原理详解与实现
  13. it男如何像黑客一样聊天qq
  14. iOS-dSYM 文件分析工具
  15. 使用.net进行视频格式转换
  16. Unity IOS设备陀螺仪控制相机旋转
  17. 大数据相关面试题整理-带答案-难一点
  18. 中国游戏企业扬帆出海,应该选择怎样的云平台?
  19. 网页打开速度很慢,怎么解决?
  20. 关于Office365邮箱附件大小限制问题

热门文章

  1. Redis的惊鸿一瞥
  2. PHP获取表单方法总结
  3. Python游戏制作(一)
  4. 图(Dijkstra,Prim,Kruskal)
  5. js基础面试题整理(包含ES5,ES6)
  6. 战略支援部队信息工程大学的计算机类,战略支援部队信息工程大学2018年硕士研究生招生简章...
  7. unity 渲染层级详解
  8. Dagger2 简介
  9. JavaScript 获取一元素的所有子元素
  10. 【学习设计模式6】单枪匹马只身一人——单例模式