restful如何更好的设计RESTful API

restful  时间:2021-08-16  阅读:()

WebService为什么不如RESTful API流行

从基本原理层次上说,REST 样式和 SOAP 样式 Web Service的区别取决于应用程序是面向资源的还是面向活动的。

例如,在传统的WebService中,一个获得天气预报的webservice会暴露一个WebMethod:string GetCityWether(string city)。

如何设计好的RESTful API之安全性

a) 对客户端做身份认证 b) 对敏感的数据做加密,并且防止篡改 c) 身份认证之后的授权 对客户端做身份认证,有几种常见的做法: 在请求中加签名参数 1. 为每个接入方分配一个密钥,并且规定一种签名的计算方法。

要求接入方的请求中必须加上签名参数。

这个做法是最简单的,但是需要确保接入方密钥的安全保存, 另外还要注意防范replay攻击。

其优点是容易理解与实现,缺点是需要承担安全保存密钥和定期更新密钥的负担,而且不够灵活,更新密钥和升级签名算法很 困难。

使用标准的HTTP身份认证机制 HTTP Basic身份认证安全性较低,必须与HTTPS配合使用。

HTTP Digest身份认证可以单独使用,具备中等程度的安全性。

HTTP Digest身份认证机制还支持插入用户自定义的加密算法,这样可以进一步提高API的安全性。

不过插入自定义加密算法在面向互联网的API中用的不是很多。

这个做法需要确保接入方“安全域-用户名-密码”三元组信息的安全保存,另外还要注意防范replay攻击。

优 点:基于标准,得到了广泛的支持(大量HTTP服务器端、客户端库)。

在服务器端做HTTP身份认证的职责可以由Web Server(例如Nginx)、App Server(例如Tomcat)、安全框架(例如Spring Security)来承担,对应用开发者来说是透明的。

HTTP身份认证机制(RFC 2617)非常好地体现了“分离关注点”的设计原则,而且保持了操作语义的可见性。

2.缺点:这类基于简单用户名+密码机制的安全性不可能高于基于非对称密钥的机制(例如数字证书)。

使用OAuth协议做身份认证 OAuth 协议适用于为外部应用授权访问本站资源的情况。

其中的加密机制与HTTP Digest身份认证相比,安全性更高。

需要注意,OAuth身份认证与HTTP Digest身份认证之间并不是相互取代的关系,它们的适用场景是不同的。

OAuth协议更适合于为面向最终用户维度的API提供授权,例如获取隶属于用 户的微博信息等等。

如果API并不是面向最终用户维度的,例如像七牛云存储这样的存储服务,这并非是OAuth协议的典型适用场景。

3.对敏感的数据做加密,并且防止篡改,常见的做法有: 部署SSL基础设施(即HTTPS),敏感数据的传输全部基于SSL。

仅对部分敏感数据做加密(例如预付费卡的卡号+密码),并加入某种随机数作为加密盐,以防范数据被篡改。

身份认证之后的授权,主要是由应用来控制。

通常应该实现某种基于角色+用户组的授权机制,这方面的框架有不少(例如Spring Security),不过大多数开发团队还是喜欢自己来实现相关功能。

-

如何测试spring restful api

在很多Java企业级应用中,Spring占据了非常重要的位置,这就导致了基本上的技术选型都是围绕着Spring来, 比方说笔者最近的项目需要开发一个Restful的API接口,选型的时候就说,客户架构师直接就拍了spring-ws,原因呢?系统中其他的模块都是用的Spring-ws,保持一致,而且社区活跃,文档丰富,遇到问题易解决。

好了,入正题。

既然选定了Spring-WS, 已经TDD入魔的我,首先想到的就是我应该怎么测试这个API接口呢? 作为业界最成熟的框架,Spring为测试其Web应用提供了非常好用的辅助类MockMvc。

首先,在项目的测试代码中加入辅助Spring Web测试的库 Gradle代码 testCompile( &.springframework:spring-test:$springVersion", &.springframework.ws:spring-ws-test:2.1.0.RELEASE", "javax.servlet:javax.servlet-api:3.0.1", &.jayway.jsonpath:json-path-assert:0.9.0" ) 其中,jsonpath库的依赖是为了更好的做json格式数据的断言。

然后,编写测试代码 Java代码 //指定使用SpringIntegration测试,并且制定了运行测试的ApplicationContext @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"classpath:spring-servlet.xml"}) public class ApiControllerIntegrationTest { @Autowired private ApiController controller; private MockMvc mockMvc; @Before public void setUp() throws Exception { //绑定需要测试的Controller到MockMvcshang mockMvc = MockMvcBuilders.standaloneSetup(controller).build(); } @Test public void testGet() throws Exception { //发出请求,在请求中可以设置一个http request可设置的所有参数 mockMvc.perform(get("/requests/1") .contentType(MediaType.APPLICATION_JSON) ept(MediaType.APPLICATION_JSON) .param("userId", "xianlinbox") ) //验证Respondse,status()中,可验证所有的HTTP Status CODE //另外,使用了jsonPath更优雅的做json属性值的验证 .andExpect(status().isOk()) .andExpect(jsonPath("$.userId").value("xianlinbox")) .andExpect(jsonPath("$.requestId").value("1")) .andExpect(jsonPath("$.requestType").value("GET")); } @Test public void testPost() throws Exception { mockMvc.perform(post("/requests") .contentType(MediaType.APPLICATION_JSON) ept(MediaType.APPLICATION_JSON) .content("this is the message") .param("userId", "xianlinbox") ) //使用print()可打印出当前测试设计的HTTP Request/Responsed的所有信息,方便定位问题 //Post方法的返回结果应该是202(HttpStatus.Created),对象创建成功 .andDo(print()) .andExpect(status().isCreated()) .andExpect(jsonPath("$.userId").value("xianlinbox")) .andExpect(jsonPath("$.requestType").value("POST")) .andExpect(jsonPath("$.message").value("this is the message")); } } testPost方法中的print()语句打印出的效果如下: MockHttpServletRequest: HTTP Method = POST Request URI = /requests Parameters = {userId=[xianlinbox]} Headers = {Content-Type=[application/json], ept=[application/json]} Handler: Type =.xianlinbox.api.ApiController Method = .xianlinbox.api.ApiController.post(java.lang.String,java.lang.String) Async: Was async started = false Async result = null Resolved Exception: Type = null ModelAndView: View name = null View = null Model = null FlashMap: MockHttpServletResponse: Status = 201 Error message = null Headers = {Content-Type=[application/json;charset=UTF-8]} Content type = application/json;charset=UTF-8 Body = {"userId":"xianlinbox","requestId":"1","requestType":"POST","message":"this is the message"} Forwarded URL = null Redirected URL = null Cookies = [] 看完了测试, 来简单的看下具体的实现代码: Java代码 @Controller public class ApiController { @RequestMapping(value = "/requests/{requestId}", method = RequestMethod.GET) @ResponseBody public Request get(@PathVariable String requestId, @RequestParam(value = "userId") String userId) { return new Request(userId, requestId, "GET"); } @RequestMapping(value = "/requests", method = RequestMethod.POST) @ResponseBody @ResponseStatus(value = HttpStatus.CREATED) public Request post(@RequestParam(value = "userId") String userId, @RequestBody String content) { Request request = new Request(userId, "1", "POST"); request.setMessage(content); return request; } } 使用RequestMapping定义URL 使用@ResponseBody表示返回json 使用@PathVariable 获取路径参数 使用@RequestParam获取request payload中的参数 使用@RequestBody获取request body 使用@ResponseStatus(value = HttpStatus.CREATED),定义返回的HTTP STATUS CODE

RESTFul API 在安全方面需要注意什么

在Rio的基础上,补充几点: 防CSRF类攻击:RESRFul API由于是面向程序,很容易被实施自动化类攻击,这类问题的反例可以参考新浪微博之前的蠕虫、强制关注等漏洞,常规的防御方法主要有:构造不可预测token、Refer校验等; 底层程序语言框架安全:和应用开发者关系不大,属运维层面安全问题,但如果忽视,开发者容易躺着中枪,这类问题的反例可以参考之前很火的Java Struts2框架执行任意代码漏洞; 第三方应用/内容安全:这里的第三方不仅是远程的,还包括本地的,例如本地调用curl不当导致的任意文件访问漏洞;

如何更好的设计RESTful API

1.接口命名规则 http://ip:端口/v1/接口名 IP:服务器IP地址 端口:Restful端口号 V1:版本号(1) 接口名: 命名规则:现有接口方法去第一个单词后,全小写命名,如: 城市信息查询, 原接口名:queryCityId (String id) Restful接口:http://ip:端口/v1/cityid 2.参数规则 参数提交方式:Application/www-form-urlencoded 参数命名:单词采取小写,复合词采取下划线分开的全小写命名。

参数规则:批量查询需有page_size以及page_num参数,避免一次性查询,部分参数需有默认值设定。

Restful接口设计原则 l 使用标准HTTP方法实现资源CURD操作; l 采用json作为API输入输出; l 以json输出错误信息。

注:Http协议详解 HTTP请求方法在 RESTfulAPI 中的典型应用 一组资源的URI,比如 http://ip:8080/v1/ user/ 列出 URI,以及该资源组中每个资源的详细信息(后者可选)。

使用给定的一组资源替换当前整组资源。

在本组资源中创建/追加一个新的资源。

该操作往往返回新资源的URL。

删除 整组资源。

单个资源的URI,比如 http://ip:8080/v1/user/1 获取 指定的资源的详细信息,格式使用JSON 替换/创建 指定的资源。

并将其追加到相应的资源组中。

把指定的资源当做一个资源组,并在其下创建/追加一个新的元素,使其隶属于当前资源。

删除 指定的元素。

PUT 和 DELETE 方法是幂等方法。

GET方法是安全方法 (不会对服务器端有修改,因此当然也是幂等的)。

支持的返回码列表: HTTP返回码 实现举例 例如,一个简单的客户管理应用: 列举所有客户: URL: GET http:// ip: 8080/v1/crm/customer 输入:无 输出:略 呈现某一位客户: URL: GET http:// ip: 8080/v1/crm/customer/[customer id] 输入:无 输出:略 新增客户: URL: POST http:// ip: 8080/v1/crm/ customer 输入:略 输出:略 更新用户: 根据更新参数,需要更新哪些参数就选哪些参数。

CloudCone:$14/年KVM-512MB/10GB/3TB/洛杉矶机房

CloudCone发布了2021年的闪售活动,提供了几款年付VPS套餐,基于KVM架构,采用Intel® Xeon® Silver 4214 or Xeon® E5s CPU及SSD硬盘组RAID10,最低每年14.02美元起,支持PayPal或者支付宝付款。这是一家成立于2017年的国外VPS主机商,提供VPS和独立服务器租用,数据中心为美国洛杉矶MC机房。下面列出几款年付套餐配置信息。CPU:...

Webhosting24:€15/年-AMD Ryzen/512MB/10GB/2TB/纽约&日本&新加坡等机房

Webhosting24是一家始于2001年的意大利商家,提供的产品包括虚拟主机、VPS、独立服务器等,可选数机房包括美国洛杉矶、迈阿密、纽约、德国慕尼黑、日本、新加坡、澳大利亚悉尼等。商家VPS主机采用AMD Ryzen 9 5950X CPU,NVMe磁盘,基于KVM架构,德国机房不限制流量,网站采用欧元计费,最低年付15欧元起。这里以美国机房为例,分享几款套餐配置信息。CPU:1core内存...

RAKsmart(年79元),云服务器年付套餐汇总 - 香港 美国 日本云服务器

RAKsmart 商家从原本只有专注于独立服务器后看到产品线比较单薄,后来陆续有增加站群服务器、高防服务器、VPS主机,以及现在也有在新增云服务器、裸机云服务器等等。机房也有增加到拥有洛杉矶、圣何塞、日本、韩国、中国香港等多个机房。在年前也有介绍到RAKsmart商家有提供年付129元的云服务器套餐,年后我们看到居然再次刷新年付云服务器低价格。我们看到云服务器低至年79元,如果有需要便宜云服务器的...

restful为你推荐
动画技术三渲二是种怎样的动画技术,比起传统3D有哪些优开发管理项目管理都包括哪些内容?色空间色差仪中L值a值b值是什么意思化学键理论什么是化学键?化学键是怎样形成的?哪些物质有化学键?那些没有?锤子手机发布会视频锤子手机发布会上,老罗说安卓不是原生的安卓这是什么意思?原生的安卓应该是什么样呢?呼叫中心系统方案呼叫中心方案一般包括哪几个方面wps表格数据恢复WPS表格如果变成这样怎么恢复系统部署方案系统规划的主要任务包括大数据人才培养哪些大学开设了大数据专业,并且已经有了应届毕业生电子商务数据分析什么是电子商务网络数据分析师
最好的虚拟主机 过期域名查询 网页空间租用 二级域名申请 bandwagonhost l5520 美国便宜货网站 softbank官网 40g硬盘 e蜗 什么是刀片服务器 中国电信测网速 上海服务器 raid10 便宜空间 外贸空间 丽萨 dnspod lamp的音标 测试网速命令 更多