简体   繁体   English

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

[英]How to differentiate between an internal & external REST API request?

On the server, is there any way to differentiate between an internal & external REST API request? 在服务器上,有没有办法区分内部和外部REST API请求?

Why? 为什么?

The reason I want to distinguish the two origins, is because I may, based on the advice, given by respondents, want to return a different data set, depending on who is trying to make the request. 我想区分这两个来源的原因是因为根据受访者给出的建议,我可能希望返回不同的数据集,具体取决于谁试图提出请求。

Summary 摘要

My definition of internal maybe incorrect. 我对内部的定义可能不正确。 In this instance, 'internal' means a request made from an XHTTP request from the same domain as the page processing the request. 在这种情况下,“内部”表示来自与处理请求的页面相同的域的XHTTP请求发出的请求。

An external call might be a user creating a Curl request from another domain. 外部呼叫可能是用户从另一个域创建Curl请求。

For instance: 例如:

http.service.ts http.service.ts

INTERNAL ANGULAR 6 REQUEST 内部角度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 template.cfm

EXTERNAL COLDFUSION REQUEST 外部冷冻请求


<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>

Please understand that I have simplified these 2 code snippets to keep things clear. 请理解我已经简化了这两个代码片段以保持清晰。

When the request hits the server, how can I tell which request has come via XHTTP and which has been sent via CFHTTP [Curl]? 当请求到达服务器时,如何通过XHTTP判断哪个请求以及哪个请求通过CFHTTP [Curl]发送?

I am using Taffy.io REST API framework, so here is a simplified method, inside a 'resources' CFC, that I might use to process the request: 我正在使用Taffy.io REST API框架,所以这里是一个简化的方法,在'资源'CFC中,我可能会用来处理请求:

resources/oauthMember.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>

Adding an extra header to one of the calls is not viable, because this can easily be spoofed. 为其中一个调用添加额外的标头是不可行的,因为这很容易被欺骗。

Any ideas? 有任何想法吗?

Environment 环境

Windows 2008R2 Lucee 4.5 IIS7+ Windows 2008R2 Lucee 4.5 IIS7 +

In short, you can't trust anything in coming request in public REST API data. 简而言之,您不能相信公共REST API数据中的任何请求。 Anything in request content/headers can be constucted by curl or custom program. 请求内容/标题中的任何内容都可以通过curl或自定义程序构建。 You, probably, may have some trust in socket Source IP address, if your web server configured accordingly and has direct access to source connection address from socket itself. 如果您的Web服务器相应配置并且可以从套接字本身直接访问源连接地址,那么您可能对套接字源IP地址有一定的信任。 This is rare case nowadays, as usually web servers now located behind load balancers, firewalls with NAT tunnels, etc. But even in that case, Source IP address probably may be used only for some sort of whitelisting. 现在这种情况很少见,因为现在通常位于负载平衡器后面的Web服务器,具有NAT隧道的防火墙等等。但即使在这种情况下,源IP地址也可能仅用于某种​​类型的白名单。 Moreover, server that has this kind of access today, may lose it tomorrow, when your application may need load balancer to scale. 而且,今天有这种访问的服务器,明天可能会失去它,当你的应用程序可能需要负载均衡器来扩展时。 Also note that user may have a HTTP proxies on a source path. 另请注意,用户可能在源路径上具有HTTP代理。 So, using source IP as API criteria looks like bad practice. 因此,使用源IP作为API标准看起来是不好的做法。

Good practice is to create public API that is invariant to caller. 好的做法是创建对调用者不变的公共API。 API calls should concentrate on REST request body and headers provided to check for theirs validity, acceptability and security. API调用应集中于提供的REST请求正文和标题,以检查其有效性,可接受性和安全性。 Indeed, many API calls should be done in sequence like “login” -> sessionToken -> “API calls with sessionToken” -> “logout with sessionToken” (token invalidated). 实际上,许多API调用应按顺序完成,如“login” - > sessionToken - >“使用sessionToken调用API” - >“使用sessionToken注销”(令牌无效)。 In that case important data (user Id, role, security context, etc) stored on server attached to sessionToken somehow. 在那种情况下,以某种方式附加到sessionToken的服务器上存储的重要数据(用户ID,角色,安全上下文等)。 Note: many API architects do not recommend to store sessionToken in cookie, as it may simplify CSRF attacks (if no other countermeasures provided). 注意:许多API架构师不建议在cookie中存储sessionToken,因为它可以简化CSRF攻击(如果没有提供其他对策)。

What you and probably many others want is to have “private” API to implement your web site functionality itself and “public” API to your customers. 您和许多其他人想要的是拥有“私有”API来实现您的网站功能本身以及为您的客户提供“公共”API。 That's a bit different story. 这是一个有点不同的故事。

Public API you document, publish (at least to customers), promise to keep unchanged during long period of time. 您记录,发布(至少向客户)的公共API,承诺在​​很长一段时间内保持不变。

Private API you may change at any moment and you may design it in a way that is comfortable to you. 您可以随时更改私有API,并且可以以对您感觉舒适的方式进行设计。 But if your site is live, anyone can still scan his own traffic and construct similar requests with curl (or something alike). 但是,如果您的网站是实时的,任何人仍然可以扫描自己的流量并使用curl(或类似的东西)构建类似的请求。 You may, however, do some tricks to made abuser's life harder, like issue some kind of JavaScript-calculated page tokens, use short-lived request chains etc, but this is not eliminated threat completely. 但是,您可能会做一些技巧来使滥用者的生活变得更加困难,例如发布某种JavaScript计算的页面令牌,使用短期请求链等,但这并不是完全消除威胁。 So API cannot relay on that “nobody can construct such request” if all data for the request may be obtained from page and traffic by legitimate user. 因此,如果请求的所有数据都可以通过合法用户从页面和流量获得,则API无法继续“无人可以构造此类请求”。

Resume: Better to have public API for customers and private API to site itself and do not mix them. 简历:最好为客户提供公共API,为站点本身提供私有API,不要混用它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM