如何区分内部和外部 REST API 请求?
How to differentiate between an internal & external REST API request?
在服务器上,有什么方法可以区分内部和外部 REST API 请求吗?
为什么?
我想区分这两个来源的原因是,根据受访者的建议,我可能想要 return 不同的数据集,这取决于谁试图提出请求.
总结
我对内部的定义可能不正确。在这种情况下,'internal' 表示请求来自与处理请求的页面相同的域的 XHTTP 请求。
外部调用可能是用户从另一个域创建 Curl 请求。
例如:
http.service.ts
内部 ANGULAR 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>
请理解,我已经简化了这 2 个代码片段以保持清晰。
当请求到达服务器时,我如何判断哪个请求是通过 XHTTP 发出的,哪个请求是通过 CFHTTP [Curl] 发送的?
我正在使用 Taffy.io REST API 框架,所以这是一个简化的方法,在 'resources' CFC 中,我可能会用它来处理请求:
resources/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>
向其中一个调用添加额外的 header 是不可行的,因为这很容易被欺骗。
有什么想法吗?
环境
Windows 2008R2
路西4.5
IIS7+
简而言之,您不能信任 public REST API 数据中的任何请求。请求 content/headers 中的任何内容都可以通过 curl 或自定义程序构造。如果您的 Web 服务器相应配置并且可以从套接字本身直接访问源连接地址,您可能对套接字源 IP 地址有一定的信任。现在这种情况很少见,因为通常 Web 服务器现在位于负载平衡器、带有 NAT 隧道的防火墙等后面。但即使在那种情况下,源 IP 地址也可能仅用于某种白名单。此外,今天具有这种访问权限的服务器明天可能会失去它,届时您的应用程序可能需要负载均衡器来扩展。另请注意,用户可能在源路径上有 HTTP 代理。因此,使用源 IP 作为 API 标准看起来是不好的做法。
好的做法是创建对调用者不变的 public API。 API 调用应集中在 REST 请求 body 和 headers 上,以检查其有效性、可接受性和安全性。实际上,许多 API 调用应该按顺序完成,例如“登录”-> sessionToken ->“API 使用 sessionToken 调用”->“使用 sessionToken 注销”(令牌无效)。在这种情况下,重要数据(用户 ID、角色、安全上下文等)以某种方式存储在附加到 sessionToken 的服务器上。注意:许多 API 架构师不建议将 sessionToken 存储在 cookie 中,因为它可能会简化 CSRF 攻击(如果没有提供其他对策)。
您和其他许多人可能想要的是拥有“私人”API 来实现您的网站功能本身和“public”API 给您的客户。这是一个有点不同的故事。
Public API 您记录、发布(至少向客户),承诺在很长一段时间内保持不变。
私有API你可以随时改变,你可以设计成你觉得舒服的方式。但是,如果您的站点是实时的,任何人仍然可以扫描他自己的流量并使用 curl(或类似的东西)构造类似的请求。但是,您可能会采取一些技巧让施虐者的日子更难过,例如发布某种 JavaScript-calculated 页面令牌、使用 short-lived 请求链等,但这并不能完全消除威胁。因此,如果请求的所有数据都可以从合法用户的页面和流量中获取,API 不能依赖“没有body 可以构造这样的请求”。
简历:
最好让客户 public API 和私人 API 自己建站,不要混用。
在服务器上,有什么方法可以区分内部和外部 REST API 请求吗?
为什么?
我想区分这两个来源的原因是,根据受访者的建议,我可能想要 return 不同的数据集,这取决于谁试图提出请求.
总结
我对内部的定义可能不正确。在这种情况下,'internal' 表示请求来自与处理请求的页面相同的域的 XHTTP 请求。
外部调用可能是用户从另一个域创建 Curl 请求。
例如:
http.service.ts
内部 ANGULAR 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>
请理解,我已经简化了这 2 个代码片段以保持清晰。
当请求到达服务器时,我如何判断哪个请求是通过 XHTTP 发出的,哪个请求是通过 CFHTTP [Curl] 发送的?
我正在使用 Taffy.io REST API 框架,所以这是一个简化的方法,在 'resources' CFC 中,我可能会用它来处理请求:
resources/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>
向其中一个调用添加额外的 header 是不可行的,因为这很容易被欺骗。
有什么想法吗?
环境
Windows 2008R2 路西4.5 IIS7+
简而言之,您不能信任 public REST API 数据中的任何请求。请求 content/headers 中的任何内容都可以通过 curl 或自定义程序构造。如果您的 Web 服务器相应配置并且可以从套接字本身直接访问源连接地址,您可能对套接字源 IP 地址有一定的信任。现在这种情况很少见,因为通常 Web 服务器现在位于负载平衡器、带有 NAT 隧道的防火墙等后面。但即使在那种情况下,源 IP 地址也可能仅用于某种白名单。此外,今天具有这种访问权限的服务器明天可能会失去它,届时您的应用程序可能需要负载均衡器来扩展。另请注意,用户可能在源路径上有 HTTP 代理。因此,使用源 IP 作为 API 标准看起来是不好的做法。
好的做法是创建对调用者不变的 public API。 API 调用应集中在 REST 请求 body 和 headers 上,以检查其有效性、可接受性和安全性。实际上,许多 API 调用应该按顺序完成,例如“登录”-> sessionToken ->“API 使用 sessionToken 调用”->“使用 sessionToken 注销”(令牌无效)。在这种情况下,重要数据(用户 ID、角色、安全上下文等)以某种方式存储在附加到 sessionToken 的服务器上。注意:许多 API 架构师不建议将 sessionToken 存储在 cookie 中,因为它可能会简化 CSRF 攻击(如果没有提供其他对策)。
您和其他许多人可能想要的是拥有“私人”API 来实现您的网站功能本身和“public”API 给您的客户。这是一个有点不同的故事。
Public API 您记录、发布(至少向客户),承诺在很长一段时间内保持不变。
私有API你可以随时改变,你可以设计成你觉得舒服的方式。但是,如果您的站点是实时的,任何人仍然可以扫描他自己的流量并使用 curl(或类似的东西)构造类似的请求。但是,您可能会采取一些技巧让施虐者的日子更难过,例如发布某种 JavaScript-calculated 页面令牌、使用 short-lived 请求链等,但这并不能完全消除威胁。因此,如果请求的所有数据都可以从合法用户的页面和流量中获取,API 不能依赖“没有body 可以构造这样的请求”。
简历: 最好让客户 public API 和私人 API 自己建站,不要混用。