微服务设计指导-纠正目前网上近90%以上错误的对于“API跨域”问题的所谓指导

背景

因为我们是前后台分离的写法;

因为我们用的是VUE/Angelar;

因为我们在开发这套东西时,存在上述两个问题,而Spring Boot2默认是不允许跨域。因此我们开发时经常会发生这样的情况:

我们有一个spring boot controller如下

/**

* 系统项目名称 org.sky.demo.redisdemo.controller RedisDemoController.java

*

* Jan 15, 2021-2:55:10 PM 2021XX公司-版权所有

*

*/packageorg.mk.demo.mvc1.api;importorg.mk.demo.mvc1.bean.Student;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;importorg.springframework.web.bind.annotation.PostMapping;importorg.springframework.web.bind.annotation.RequestBody;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.ResponseBody;importorg.springframework.web.bind.annotation.RestController;importio.swagger.annotations.Api;importio.swagger.annotations.ApiOperation;/** *  * RedisDemoController *  *  * Jan 15, 2021 2:55:10 PM *  *@version1.0.0 *  */@RestController@RequestMapping("/demo")@Api(tags ="demo mvc1")publicclassApiController{privateLogger logger = LoggerFactory.getLogger(this.getClass());@ApiOperation(value ="修改学生信息接口", notes ="返回success或者是fail")@PostMapping(value ="/updStudent", produces ="application/json")@ResponseBodypublicString updStudent(@RequestBodyStudent std) {        logger.info(">>>>>>intp mvc1->updStudent");        logger.info(">>>>>>name->"+ std.getName() +"  age->"+ std.getAge());return"success";    }}

我们有一个vue端的axios提交如下:

/src/utils/request.js

importaxiosfrom'axios'axios.interceptors.response.use(response=>{constdata = response.dataconsole.log(data)  },  error => {console.log('error', error)  })exportconstrequest = axios

HelloWorld.vue

跨域访问import{request}from'@/utils/request.js'exportdefault{name:'HelloWorld',methods: {    updateStudent () {      request.post('http://localhost:9081/demo/updStudent', {'name':'abc','age':10})    }  }}

运行后,我们点了一下这个“按钮”,然后我们在浏览器的web console得到了如下这样的“跨域不允许”的报错

已拦截跨源请求:同源策略禁止读取位于 http://localhost:9081/demo/updStudent 的远程资源。(原因:CORS 头缺少 'Access-Control-Allow-Origin')。状态码:403。

错误的做法来了

/**

* 系统项目名称 org.mk.demo.skypayment.config.webmvc WebMvcConfig.java

*

* Feb 21, 2022-10:30:19 AM 2022XX公司-版权所有

*

*/package org.mk.demo.config;importjava.util.ArrayList;importjava.util.Collections;importjava.util.List;importorg.springframework.beans.factory.annotation.Value;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.web.cors.CorsConfiguration;importorg.springframework.web.cors.UrlBasedCorsConfigurationSource;importorg.springframework.web.filter.CorsFilter;importorg.springframework.web.servlet.config.annotation.CorsRegistry;importorg.springframework.web.servlet.config.annotation.WebMvcConfigurer;/**

*

* WebMvcConfig

*

*

* Feb 21, 2022 10:30:19 AM

*

* @version 1.0.0

*

*/@ConfigurationpublicclassWebMvcConfigimplementsWebMvcConfigurer{/**    * 跨域配置    */@Value("${project.basePath}")    privateStringbasePath;@Beanpublic CorsFilter corsFilter() {        UrlBasedCorsConfigurationSource source =newUrlBasedCorsConfigurationSource();        CorsConfiguration config =newCorsConfiguration();        config.setAllowCredentials(true);// 允许访问的客户端域名List allowedOriginPatterns =newArrayList<>();        allowedOriginPatterns.add("*");        config.setAllowedOrigins(allowedOriginPatterns);// 允许服务端访问的客户端请求头config.addAllowedHeader("*");// 允许访问的方法名,GET POST等config.addAllowedMethod("*");// 对接口配置跨域设置source.registerCorsConfiguration("/**", config);returnnewCorsFilter(source);    }}

改完后我们再去点一下vue端的按钮,哎,请求正常进来了,好了,完事了,上生产了。

然后生产生产,定期有安全扫描,每年还有等保资质审核,等保不过,你网站也别开了就,直接到时可以找个电子厂上班了哈。

一看,哎呀。。。到处API都有这个,然后此时再一看我们的商城相关的系统已经成下面这样了

任何一根API的改动,就得来一次回归测试。。。一般来说比如说中台系统,几十个模块。。。几千个API,这个改大了。

不改吗。。。如梗在咽喉,唉。。。

正确的做法

因此,我们在一开始碰到这种问题时就需要引起注意,这边只教各位对的做法。而不是简单的什么后台来一句:allow(*),网上90%以上的教程都这种, 全是错的 !

/**

* 系统项目名称 org.mk.demo.skypayment.config.webmvc WebMvcConfig.java

*

* Feb 21, 2022-10:30:19 AM 2022XX公司-版权所有

*

*/package org.mk.demo.config;importjava.util.ArrayList;importjava.util.Collections;importjava.util.List;importorg.springframework.beans.factory.annotation.Value;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.web.cors.CorsConfiguration;importorg.springframework.web.cors.UrlBasedCorsConfigurationSource;importorg.springframework.web.filter.CorsFilter;importorg.springframework.web.servlet.config.annotation.CorsRegistry;importorg.springframework.web.servlet.config.annotation.WebMvcConfigurer;/**

*

* WebMvcConfig

*

*

* Feb 21, 2022 10:30:19 AM

*

* @version 1.0.0

*

*/@ConfigurationpublicclassWebMvcConfigimplementsWebMvcConfigurer{/**

    * 跨域配置

    */@BeanpublicCorsFiltercorsFilter() {UrlBasedCorsConfigurationSourcesource = newUrlBasedCorsConfigurationSource();CorsConfigurationconfig = newCorsConfiguration();        config.setAllowCredentials(true);// 允许访问的客户端域名List allowedOriginPatterns = newArrayList<>();        allowedOriginPatterns.add(basePath);//config.setAllowedOriginPatterns(allowedOriginPatterns);config.setAllowedOrigins(allowedOriginPatterns);// 允许服务端访问的客户端请求头config.addAllowedHeader("*");// 允许访问的方法名,GET POST等config.addAllowedMethod("*");// 对接口配置跨域设置source.registerCorsConfiguration("/**", config);returnnewCorsFilter(source);    }}

此处的这一句:

List<String> allowedOriginPatterns = new ArrayList<>();

这一句话就是把你允许访问后台的域名一个个加进去,而我们在设计上应该如下操作:

把允许的访问的域名,一个个加到以下这个List<String>中,可以用一个mongoDb的collection存所有的“被允许的域名”;

然后把这个List给到config.setAllowedOrigins(allowedOriginPatterns);

最后,以上代码适合spring boot 2.1~2.3,对于2.4及以后版本上述的config.setAllowedOrigins要写成“config.setAllowedOriginPatterns(allowedOriginPatterns);”

我们来看,正确设置了跨域后的访问吧。

首先,我们在.yml里配置一个允许的跨域访问(这块我为了演示因此配在.yml文件里了,各位生产上一定要按照我的核心设计来做这件事以便于应用上扩展性更好)。

server:port:9081tomcat:max-http-post-size: -1max-http-header-size:10240000spring:application:name: mvc1servlet:multipart:max-file-size:10MBmax-request-size:10MBswagger:enable: falseproject:basePath:http://localhost:8080

/**

* 系统项目名称 org.mk.demo.skypayment.config.webmvc WebMvcConfig.java

*

* Feb 21, 2022-10:30:19 AM 2022XX公司-版权所有

*

*/package org.mk.demo.config;importjava.util.ArrayList;importjava.util.Collections;importjava.util.List;importorg.springframework.beans.factory.annotation.Value;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.web.cors.CorsConfiguration;importorg.springframework.web.cors.UrlBasedCorsConfigurationSource;importorg.springframework.web.filter.CorsFilter;importorg.springframework.web.servlet.config.annotation.CorsRegistry;importorg.springframework.web.servlet.config.annotation.WebMvcConfigurer;/**

*

* WebMvcConfig

*

*

* Feb 21, 2022 10:30:19 AM

*

* @version 1.0.0

*

*/@ConfigurationpublicclassWebMvcConfigimplementsWebMvcConfigurer{/**    * 跨域配置    */@Value("${project.basePath}")    privateStringbasePath;@Beanpublic CorsFilter corsFilter() {        UrlBasedCorsConfigurationSource source =newUrlBasedCorsConfigurationSource();        CorsConfiguration config =newCorsConfiguration();        config.setAllowCredentials(true);// 允许访问的客户端域名List allowedOriginPatterns =newArrayList<>();        allowedOriginPatterns.add(basePath);// config.setAllowedOriginPatterns(allowedOriginPatterns);config.setAllowedOrigins(allowedOriginPatterns);// config.addAllowedOrigin(serverPort);// 允许服务端访问的客户端请求头config.addAllowedHeader("*");// 允许访问的方法名,GET POST等config.addAllowedMethod("*");// 对接口配置跨域设置source.registerCorsConfiguration("/**", config);returnnewCorsFilter(source);    }}

我们在vue上点一下原来这个按钮,前端什么都不需要动。

看,后台请求进来了。

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

推荐阅读更多精彩内容