前后端分离后API交互如何保证数据安全性?

一、前言

前后端分离的开发方式,我们以接口为标准来进行推动,定义好接口,各自开发自己的功能,最后进行联调整合。无论是开发原生的APP还是webapp还是PC端的软件,只要是前后端分离的模式,就避免不了调用后端提供的接口来进行业务交互。

网页或者app,只要抓下包就可以清楚的知道这个请求获取到的数据,这样的接口对爬虫工程师来说是一种福音,要抓你的数据简直轻而易举。

数据的安全性非常重要,特别是用户相关的信息,稍有不慎就会被不法分子盗用,所以我们对这块要非常重视,容不得马虎。

二、如何保证API调用时数据的安全性?

1、通信使用https

2、请求签名,防止参数被篡改

3、身份确认机制,每次请求都要验证是否合法

4、APP中使用ssl pinning防止抓包操作

5、对所有请求和响应都进行加解密操作

6、等等方案…….

三、对所有请求和响应都进行加解密操作

方案有很多种,当你做的越多,也就意味着安全性更高,今天我跟大家来介绍一下对所有请求和响应都进行加解密操作的方案,即使能抓包,即使能调用我的接口,但是我返回的数据是加密的,只要加密算法够安全,你得到了我的加密内容也对我没什么影响。

像这种工作最好做成统一处理的,你不能让每个开发都去关注这件事情,如果让每个开发去关注这件事情就很麻烦了,返回数据时还得手动调用下加密的方法,接收数据后还得调用下解密的方法。

为此,我基于Spring Boot封装了一个Starter, 内置了AES加密算法。GitHub地址如下:

https://github.com/yinjihuan/spring-boot-starter-encrypt

先来看看怎么使用,可以下载源码,然后引入即可,然后在启动类上增加@EnableEncrypt注解开启加解密操作:

增加加密的key配置:

  • spring.encrypt.key:加密key,必须是16位
  • spring.encrypt.debug:是否开启调试模式,默认为false,如果为true则不启用加解密操作

为了考虑通用性,不会对所有请求都执行加解密,基于注解来做控制

响应数据需要加密的话,就在Controller的方法上加@Encrypt注解即可。

当我们访问/list接口时,返回的数据就是加密之后base64编码的格式。

还有一种操作就是前段提交的数据,分为2种情况,一种是get请求,这种暂时没处理,后面再考虑,目前只处理的post请求,基于json格式提交的方式,也就是说后台需要用@RequestBody接收数据才行, 需要解密的操作我们加上@Decrypt注解即可。

加了@Decrypt注解后,前端提交的数据需要按照AES加密算法,进行加密,然后提交到后端,后端这边会自动解密,然后再映射到参数对象中。

上面讲解的都是后端的代码,前端使用的话我们以js来讲解,当然你也能用别的语言来做,如果是原生的安卓app也是用java代码来处理。

*前端需要做的就2件事情:*

1、统一处理数据的响应,在渲染到页面之前进行解密操作

2、当有POST请求的数据发出时,统一加密

js加密文件请参考我GitHub中encrypt中的aes.js,crypto-js.js,pad-zeropadding.js

我们以axios来作为请求数据的框架,用axios的拦截器来统一处理加密解密操作

首先还是要封装一个js加解密的类,需要注意的是加密的key需要和后台的对上,不然无法相互解密,代码如下:

axios拦截器中统一处理代码:

到此为止,我们就为整个前后端交互的通信做了一个加密的操作,只要加密的key不泄露,别人得到你的数据也没用,问题是如何保证key不泄露呢?

服务端的安全性较高,可以存储在数据库中或者配置文件中,毕竟在我们自己的服务器上,最危险的其实就时前端了,app还好,可以打包,但是要防止反编译等等问题。

如果是webapp则可以依赖于js加密来实现,下面我给大家介绍一种动态获取加密key的方式,只不过实现起来比较复杂,我们不上代码,只讲思路:

加密算法有对称加密和非对称加密,AES是对称加密,RSA是非对称加密。之所以用AES加密数据是因为效率高,RSA运行速度慢,可以用于签名操作。

我们可以用这2种算法互补,来保证安全性,用RSA来加密传输AES的秘钥,用AES来加密数据,两者相互结合,优势互补。

其实大家理解了HTTPS的原理的话对于下面的内容应该是一看就懂的,HTTPS比HTTP慢的原因都是因为需要让客户端与服务器端安全地协商出一个对称加密算法。剩下的就是通信时双方使用这个对称加密算法进行加密解密。

1、客户端启动,发送请求到服务端,服务端用RSA算法生成一对公钥和私钥,我们简称为pubkey1,prikey1,将公钥pubkey1返回给客户端。

2、客户端拿到服务端返回的公钥pubkey1后,自己用RSA算法生成一对公钥和私钥,我们简称为pubkey2,prikey2,并将公钥pubkey2通过公钥pubkey1加密,加密之后传输给服务端。

3、此时服务端收到客户端传输的密文,用私钥prikey1进行解密,因为数据是用公钥pubkey1加密的,通过解密就可以得到客户端生成的公钥pubkey2

4、然后自己在生成对称加密,也就是我们的AES,其实也就是相对于我们配置中的那个16的长度的加密key,生成了这个key之后我们就用公钥pubkey2进行加密,返回给客户端,因为只有客户端有pubkey2对应的私钥prikey2,只有客户端才能解密,客户端得到数据之后,用prikey2进行解密操作,得到AES的加密key,最后就用加密key进行数据传输的加密,至此整个流程结束。

四、spring-boot-starter-encrypt原理

最后我们来简单的介绍下spring-boot-starter-encrypt的原理吧,也让大家能够理解为什么Spring Boot这么方便,只需要简单的配置一下就可以实现很多功能。

启动类上的@EnableEncrypt注解是用来开启功能的,通过@Import导入自动配置类

EncryptAutoConfiguration中配置请求和响应的处理类,用的是Spring中的RequestBodyAdvice和ResponseBodyAdvice,在Spring中对请求进行统计处理比较方便。如果还要更底层去封装那就要从servlet那块去处理了。

通过RequestBodyAdvice和ResponseBodyAdvice就可以对请求响应做处理了,大概的原理就是这么多了。

前后端分离后API交互如何保证数据安全性的更多相关文章

  1. 前后端分离后API交互如何保证数据安全性?

    一.前言 前后端分离的开发方式,我们以接口为标准来进行推动,定义好接口,各自开发自己的功能,最后进行联调整合.无论是开发原生的APP还是webapp还是PC端的软件,只要是前后端分离的模式,就避免不了 ...

  2. Django:前后端分离后联调给前端传数据

    实现前后端分离后,有了下面几点改变: 1.服务器一分为二,前后端分别部署,静态资源放在前端服务器,业务代码放在后的服务器 2.前端服务器需要接收Http请求(一般使用node.js) 3.前端服务器需 ...

  3. 前后端API交互如何保证数据安全性

    前后端分离的开发方式,我们以接口为标准来进行推动,定义好接口,各自开发自己的功能,最后进行联调整合.无论是开发原生的APP还是webapp还是PC端的软件,只要是前后端分离的模式,就避免不了调用后端提 ...

  4. 前后端API交互如何保证数据安全性?(转)

    前言 前后端分离的开发方式,我们以接口为标准来进行推动,定义好接口,各自开发自己的功能,最后进行联调整合.无论是开发原生的APP还是webapp还是PC端的软件,只要是前后端分离的模式,就避免不了调用 ...

  5. 前后端API交互如何保证数据安全性?

    前言 前后端分离的开发方式,我们以接口为标准来进行推动,定义好接口,各自开发自己的功能,最后进行联调整合.无论是开发原生的APP还是webapp还是PC端的软件,只要是前后端分离的模式,就避免不了调用 ...

  6. 前后端分离后台api接口框架探索

    前言 很久没写文章了,今天有时间,把自己一直以来想说的,写出来,算是一种总结吧!  这篇文章主要说前后端分离模式下(也包括app开发),自己对后台框架和与前端交互的一些理解和看法.     前后端分离 ...

  7. SpringBoot电商项目实战 — 前后端分离后的优雅部署及Nginx部署实现

    在如今的SpringBoot微服务项目中,前后端分离已成为业界标准使用方式,通过使用nginx等代理方式有效的进行解耦,并且前后端分离会为以后的大型分布式架构.弹性计算架构.微服务架构.多端化服务(多 ...

  8. 如何处理好前后端分离的 API 问题(转载自知乎)

    9 个月前 API 都搞不好,还怎么当程序员?如果 API 设计只是后台的活,为什么还需要前端工程师. 作为一个程序员,我讨厌那些没有文档的库.我们就好像在操纵一个黑盒一样,预期不了它的正常行为是什么 ...

  9. 前后端分离&接口API设计学习报告

    接口API设计学习报告 15331023 陈康怡 什么是API? API即Application Programming Interface.API是一种通道,负责一个程序与另一个程序的沟通.而对于w ...

随机推荐

  1. SQLite C++操作类

    为了方便SQLite的使用,封装了一个SQLite的C++类,同时支持ANSI 和UNICODE编码.代码如下:   头文件(SQLite.h) [cpp] view plaincopy /***** ...

  2. JVM的内存空间

    一.JVM运行起来,就会给内存划分空间,这块空间成为运行时数据区.运行时数据区主要划分为以下几部分内容: 1.栈 每一个线程运行起来的都会对应一个栈(线程栈),栈中的数据是该线程独有的,不会产生资源共 ...

  3. js图片预加载实现!

    var myImage = (function(){ var imgNode = document.createElement( 'img' ); document.body.appendChild( ...

  4. Docker系列(十五):Openshift 简介

    1.简单了解openshift相关组件 1.openshift是基于容器技术构建的一个云平台 2.kubernetes是容器编排组件 3.docker是容器引擎驱动组件 4.openshift在Pas ...

  5. Python学习day39-并发编程(各种锁)

    figure:last-child { margin-bottom: 0.5rem; } #write ol, #write ul { position: relative; } img { max- ...

  6. 第一周课堂笔记2th

    上课笔记2th https://mubu.com/doc/2gxvIvVLG0(老师笔记网址) 1.     python python运行过程 把源代码转化成字节码(机器不能识别) 也可能不产生py ...

  7. parameter– tRPRE and tRPST

    DDR读数据有效之前,有一段时间DQS(DQS#)需为低(高),此段时间即为read preamble,tRPRE. 同理,读数据结束之前,某段时间为read postamble,tRPST.

  8. bootstrap面包屑在ie8下显示重叠,鼠标点击显示效果正常

    ie8下加载后的显示 点击之后的显示 主要是li标签宽度auto引起的,可以设置li标签的最小宽度 <ol class="breadcrumb"> <li id= ...

  9. Golang Learn Log #0

    Print/Printf 区别 Print: 可以打印出字符串, 和变量 fmt.Println(var) //right fmt.Println("string") //righ ...

  10. 软件-MQ-MQ:IBM MQ

    ylbtech-软件-MQ-MQ:MQ(IBM MQ) MQ传递主干,在世界屡获殊荣. 它帮您搭建企业服务总线(ESB)的基础传输层.IBM WebSphere MQ为SOA提供可靠的消息传递.它为经 ...