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

MineServer:洛杉矶CN2 GIA VPS/512MB内存/20GB NVME/800GB流量/200Mbps/KVM,58元/季

mineserver怎么样?mineserver是一家国人商家,主要提供香港CN2 KVM VPS、香港CMI KVM VPS、日本CN2 KVM VPS、洛杉矶cn2 gia端口转发等服务,之前介绍过几次,最近比较活跃。这家新推出了洛杉矶CN2 GIA VPS,512MB内存/20GB NVME/800GB流量/200Mbps/KVM,58元/季,并且进行了带宽升级,同时IP更改为美国IP。点击...

DogYun香港BGP月付14.4元主机简单测试

前些天赵容分享过DogYun(狗云)香港BGP线路AMD 5950X经典低价云服务器的信息(点击查看),刚好账户还有点余额够开个最低配,所以手贱尝试下,这些贴上简单测试信息,方便大家参考。官方网站:www.dogyun.com主机配置我搞的是最低款优惠后14.4元/月的,配置单核,512MB内存,10GB硬盘,300GB/50Mbps月流量。基本信息DogYun的VPS主机管理集成在会员中心,包括...

UCloud:全球大促降价,云服务器全网最低价,1核1G快杰云服务器47元/年

ucloud:全球大促活动降价了!这次云服务器全网最低价,也算是让利用户了,UCloud商家调低了之前的促销活动价格,并且新增了1核1G内存配置快杰型云服务器,价格是47元/年(也可选2元首月),这是全网同配置最便宜的云服务器了!UCloud全球大促活动促销机型有快杰型云服务器和通用型云服务器,促销机房国内海外都有,覆盖全球20个城市,具体有北京、上海、广州、香港、 台北、日本东京、越南胡志明市、...

restful为你推荐
74ls0074ls00的两入端在电路中如何接注册电子邮件电子邮箱怎么注册呢u盾证书U盾证书在哪里?网不易怎样解决网瘾问题混乱模式拳皇2002李梅的混乱模式出招通话宝什么是中国电信通话宝?具体说一下ldap统一用户认证介绍NIPS是什么认证?it人物怎么成为一个IT人士广州品牌网站设计广州哪家品牌设计公司好?大数据人才培养哪些大学开设了大数据专业,并且已经有了应届毕业生
国内域名注册 域名注册信息查询 godaddy域名解析 ix主机 美国主机网 l5520 info域名 php探针 typecho 日本空间 gg广告 坐公交投2700元 admit的用法 新家坡 腾讯实名认证中心 metalink t云 多线空间 服务器维护 畅行云 更多