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

趣米云(18元/月)香港三网CN2云服器低至;1核1G/30G系统盘+20G数据盘/10M带宽

趣米云怎么样?趣米云是创建于2021年的国人IDC商家,虽然刚刚成立,但站长早期为3家IDC提供技术服务,已从业2年之久,目前主要从事出售香港vps、香港独立服务器、香港站群服务器等,目前在售VPS线路有三网CN2、CN2 GIA,该公司旗下产品均采用KVM虚拟化架构。由于内存资源大部分已售,而IP大量闲置,因此我们本月新增1c1g优惠套餐。点击进入:趣米云官方网站地址香港三网CN2云服务器机型活...

百纵科技:美国独立服务器租用/高配置;E52670/32G内存/512G SSD/4IP/50M带宽,999元/月

百纵科技怎么样?百纵科技国人商家,ISP ICP 电信增值许可证的正规公司,近期上线美国C3机房洛杉矶独立服务器,大带宽/高配置多ip站群服务器。百纵科技拥有专业技术售后团队,机器支持自动化,自助安装系统 重启,开机交付时间 30分钟内交付!美国洛杉矶高防服务器配置特点: 硬件配置高 线路稳定 洛杉矶C3机房等级T4 平价销售,支持免费测试,美国独服适合做站,满意付款。点击进入:百纵科技官方网站地...

georgedatacenter:美国VPS可选洛杉矶/芝加哥/纽约/达拉斯机房,$20/年;洛杉矶独立服务器39美元/月

georgedatacenter怎么样?georgedatacenter这次其实是两个促销,一是促销一款特价洛杉矶E3-1220 V5独服,性价比其实最高;另外还促销三款特价vps,大家可以根据自己的需要入手。georgedatacenter是一家成立于2019年的美国vps商家,主营美国洛杉矶、芝加哥、达拉斯、新泽西、西雅图机房的VPS、邮件服务器和托管独立服务器业务。georgedatacen...

restful为你推荐
商品管理手机千牛 商品管理用哪个好啊 我想买高级版的 不知道哪个比较好it英语形式主语it的用法现在网现在网上到处都是招聘带车司机的工作是真的吗?化学键理论现代化学键理论认为苯环结构中不存在单双键交替结构,可以作为证据的事实是①苯不能使酸性KMnO 4 溶液褪2g内存条2G内存是什么概念ldap统一用户认证介绍H3CTE的H3CTE认证介绍锤子手机发布会视频锤子手机怎么样 锤子手机评测阿里学院首页在阿里学院必须实名认证吗什么是无线上网WIFI无线网络是什么网络?广州品牌网站设计本人的公司需要专业的品牌形象设计和网站建设(我们是新的化妆品牌),不知道在广州哪家营销策划公司性价比高?
二级域名查询 VPS之家 花生壳免费域名 arvixe 主机 2017年黑色星期五 福建天翼加速 日本bb瘦 域名评估 流量计费 服务器托管什么意思 微软服务器操作系统 秒杀品 购买空间 中国联通宽带测试 网站防护 博客域名 数据湾 碳云 accountsuspended 更多