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

[6.18]DogYun:充100送10元,态云7折,经典云8折,独立服务器月省100元,幸运大转盘最高5折

DogYun是一家2019年成立的国人主机商,提供VPS和独立服务器租用等,数据中心包括中国香港、美国洛杉矶、日本、韩国、德国、荷兰等,其中VPS包括常规VPS(经典云)和按小时计费VPS(动态云),使用自行开发的面板和管理系统,支持自定义配置,动态云各个硬件独立按小时计费,带宽按照用户使用量计费(不使用不计费)或者购买流量包,线路也可以自行切换。目前商家发布了6.18促销方案,新购动态云7折,经...

星梦云-年中四川100G高防云主机月付仅60元,西南高防月付特价活动,,买到就是赚到!

官方网站:点击访问星梦云活动官网活动方案:机房CPU内存硬盘带宽IP防护流量原价活动价开通方式成都电信优化线路4vCPU4G40G+50G10Mbps1个100G不限流量210元/月 99元/月点击自助购买成都电信优化线路8vCPU8G40G+100G15Mbps1个100G不限流量370元/月 160元/月点击自助购买成都电信优化线路16vCPU16G40G+100G20Mb...

华纳云-618大促3折起,18元/月买CN2 GIA 2M 香港云,物理机高防同享,10M带宽独享三网直连,无限流量!

官方网站:点击访问华纳云活动官网活动方案:一、香港云服务器此次推出八种配置的香港云服务器,满足不同行业不同业务规模的客户需求,同时每种配置的云服务都有不同的带宽选择,灵活性更高,可用性更强,性价比更优质。配置带宽月付6折季付5.5折半年付5折年付4.5折2年付4折3年付3折购买1H1G2M/99180324576648直达购买5M/17331556710081134直达购买2H2G2M892444...

restful为你推荐
文本分析文本分析时,都有哪些去噪的方式轻应用轻推的订阅号和轻应用有什么区别?网络设备图标显示联网的UPNP设备的图标是什么东西网络地址分类A、B、C三类网络地址是如何划分的?请解释的通俗一点。accesspoint如何设置中国移动的APN(Access Point Names)接入点?accesspoint手机APN怎么设置u盾证书“U盾”和“数字证书”有什么区别?化学键理论价键理论和分子轨道理论的主要区别是什么封包是什么dnf封包是什么软件更新不可用三星GALAXY S3出现:“您的设备已修改。软件更新不可用”。系统如何解决?
主机域名 hostigation siteground 国内永久免费云服务器 网站保姆 创宇云 轻博 windows2003iso 镇江联通宽带 新天域互联 七夕促销 hktv 免费私人服务器 重庆电信服务器托管 starry 成都主机托管 稳定空间 腾讯网盘 石家庄服务器 phpwind论坛 更多