如何区分内部和外部REST API请求?

时间:2019-02-02 10:10:29

标签: angular api http coldfusion taffy

在服务器上,是否可以区分内部和外部REST API请求?

为什么?

我之所以要区分这两个来源,是因为根据受访者的建议,我可能想返回另一个数据集,具体取决于谁在尝试发出请求。

摘要

我对内部的定义可能不正确。在这种情况下,“内部”是指来自XHTTP请求的请求,该请求来自与处理请求的页面相同的域。

外部呼叫可能是用户从另一个域创建Curl请求。

例如:

http.service.ts

内部角度6请求


fetchLogin(formData: any): Observable<any> {
    let req = null;
    let headers = null;
    headers = {
      reportProgress: false,
      headers: new HttpHeaders({
        'email': formData['email'],
        'password': formData['password']
      })
    };
    req = new HttpRequest('POST', this.restApiUrl + this.restApiUrlEndpoint + '/oauth/', '', headers);
    return this.http.request(req)
    .map( (data) => {
      return 'body' in data ? data['body'] : null;
    })
    .pipe(
      catchError(this.handleError)
    );
  }

template.cfm

外部冷熔要求


<cfset httpUrl = request.restApiUrl & request.restApiUrlEndpoint & "/oauth/">

<cfhttp url="#httpUrl#" method="post" result="result" timeout="30">
  <cfhttpparam type="header" name="email" value="foo@bar.com" />
  <cfhttpparam type="header" name="password" value="foo" />
</cfhttp>

请理解,我已经简化了这两个代码段,以使内容保持清楚。

当请求到达服务器时,如何确定哪个请求是通过XHTTP发出的,以及哪个请求是通过CFHTTP [Curl]发送的?

我正在使用Taffy.io REST API框架,因此这是“资源” CFC中的一种简化方法,可用于处理请求:

资源/oauthMember.cfc

<cfcomponent extends="taffy.core.resource" taffy_uri="/oauth">

<cffunction name="post">
  <cfset var local = StructNew()>
  <cfset local.data['email'] = "">
  <cfset local.data['password'] = "">
  <cfset local.requestBody = getHttpRequestData().headers>
  <cftry>
    <cfset local.data['email'] = Trim(local.requestBody['email'])>
    <cfset local.data['password'] = Trim(local.requestBody['password'])>
    <cfcatch>
    </cfcatch>
  </cftry>
  ...processing code
  <cfreturn representationOf(local.data) />
</cffunction>

</cfcomponent>

向其中一个调用添加额外的标头不可行,因为这很容易被欺骗。

有什么想法吗?

环境

Windows 2008R2 露西4.5 IIS7 +

1 个答案:

答案 0 :(得分:3)

简而言之,您无法信任公共REST API数据中即将到来的请求中的任何内容。请求内容/标题中的任何内容都可以通过curl或自定义程序来构造。如果您的Web服务器进行了相应的配置,并且可以直接从套接字本身访问源连接地址,则可能对套接字源IP地址有些信任。如今,这种情况很少见,因为通常Web服务器现在位于负载均衡器,具有NAT隧道的防火墙等后面。但是即使在那种情况下,源IP地址也可能仅用于某种​​白名单。此外,当您的应用程序可能需要负载均衡器进行扩展时,今天拥有这种访问权限的服务器可能会在明天丢失它。还要注意,用户可能在源路径上有一个HTTP代理。因此,将源IP用作API标准似乎是一种不好的做法。

优良作法是创建对调用者不变的公共API。 API调用应集中在REST请求主体和提供的标头上,以检查其有效性,可接受性和安全性。实际上,许多API调用应按顺序执行,例如“登录”-> sessionToken->“使用sessionToken进行API调用”->“使用sessionToken退出”(令牌无效)。在那种情况下,重要数据(用户ID,角色,安全上下文等)以某种方式存储在连接到sessionToken的服务器上。注意:许多API架构师不建议将sessionToken存储在cookie中,因为它可以简化CSRF攻击(如果未提供其他对策)。

您以及可能还有许多其他人想要的是拥有“私有” API来实现您的网站功能本身,并拥有“公共” API给您的客户。那是另外一个故事。

您记录,发布(至少向客户发布)的公共API承诺长时间保持不变。

您可以随时更改私有API,并且可以按照自己喜欢的方式进行设计。但是,如果您的网站是在线的,那么任何人仍然可以扫描自己的流量并使用curl(或类似方式)构造类似的请求。但是,您可能会采取一些技巧使滥用者的生活更加艰难,例如发出某种JavaScript计算的页面令牌,使用短暂的请求链等,但这并不能完全消除威胁。因此,如果合法用户可以从页面和访问量中获取请求的所有数据,那么API就无法继续“没人可以构造这样的请求”。

恢复: 最好是为客户提供公共API,并让私有API自己定位并不要混在一起。