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 输入:略 输出:略 更新用户: 根据更新参数,需要更新哪些参数就选哪些参数。

易探云:买香港/美国/国内云服务器送QQ音乐绿钻豪华版1年,价值180元

易探云产品限时秒杀&QQ音乐典藏活动正在进行中!购买易探云香港/美国云服务器送QQ音乐绿钻豪华版1年,价值180元,性价比超级高。目前,有四大核心福利产品推荐:福利一、香港云服务器1核1G2M,仅218元/年起(香港CN2线路,全球50ms以内);福利二、美国20G高防云服务器1核1G5M,仅336元/年起(美国BGP线路,自带20G防御);福利三、2G虚拟主机低至58.8元/年(更有免费...

Linode 18周年庆典活动 不断改进产品结构和体验

今天早上相比很多网友和一样收到来自Linode的庆祝18周年的邮件信息。和往年一样,他们会回顾在过去一年中的成绩,以及在未来准备改进的地方。虽然目前Linode商家没有提供以前JP1优化线路的机房,但是人家一直跟随自己的脚步在走,确实在云服务器市场上有自己的立足之地。我们看看过去一年中Linode的成就:第一、承诺投入 100,000 美元来帮助具有社会意识的非营利组织,促进有价值的革新。第二、发...

简单测评melbicom俄罗斯莫斯科数据中心的VPS,三网CN2回国,电信双程cn2

melbicom从2015年就开始运作了,在国内也是有一定的粉丝群,站长最早是从2017年开始介绍melbicom。上一次测评melbicom是在2018年,由于期间有不少人持续关注这个品牌,而且站长貌似也听说过路由什么的有变动的迹象。为此,今天重新对莫斯科数据中心的VPS进行一次简单测评,数据仅供参考。官方网站: https://melbicom.net比特币、信用卡、PayPal、支付宝、银联...

restful为你推荐
怎么发邮件怎样发送邮件?自己动手写操作系统自己动手编写操作系统 现代操作系统两本书哪个好余额宝收益走势图余额宝10000元一年收益多少制作证书用excel如何制作证书模板化学键理论什么是化学键?化学键是怎样形成的?哪些物质有化学键?那些没有?说明书之家网站哪里有SONY专业摄像机的使用说明书无线存储为什么wifi连接上了显示保存何解封包是什么这个七月半封包怎么填国外视频聊天网址国外多人视频聊天网站求好心人帮忙!red5集群zookeeper集群为什么是3个以上节点?
西部数码vps 华为云服务 80vps 免费ftp空间申请 ibox官网 中国智能物流骨干网 40g硬盘 空间论坛 中国网通测速 广州虚拟主机 apnic 中国电信宽带测速 hdchina 美国主机 发证机构 hosting linux命令vi 万网主机代理 宿迁服务器托管 邮件服务器是什么 更多