C# Recaptcha和Web API—验证令牌的良好REST实践
我有一系列Web API控制器,它们返回AngularJS前端要使用的数据 我担心编写一个机器人的脚本是非常容易的,它只需要通过调用来敲打它,并从我的数据库中提取所有数据。虽然这些信息是免费提供的,但我花了很多时间/周/月/年来整理这些信息-这确实是我网站的整个USP。如果有人仅仅通过从服务中提取数据就偷走了我的数据,我会很难过 简单地添加Authorize不会有帮助,因为它可以免费注册 我已经决定,我将在每个请求中向API提交某种令牌,该API将得到验证。基本上,这将是一个已解决的验证码,但它可能在未来有所不同,所以我将使其可扩展。因此,我将发送一个令牌类型和一个?token=TypeID,TokenValue参数中的令牌值,并使用一个类型转换器来获取它并将其转换为token对象 所以,我的问题是-向Web API控制器发送令牌和请求的最佳实践是什么?我是这样做的,对吗?我已经读到,发送querystring来进行身份验证不是非常RESTful的,但是它工作得非常好 概念证明样本 我的控制器:C# Recaptcha和Web API—验证令牌的良好REST实践,c#,rest,asp.net-web-api,C#,Rest,Asp.net Web Api,我有一系列Web API控制器,它们返回AngularJS前端要使用的数据 我担心编写一个机器人的脚本是非常容易的,它只需要通过调用来敲打它,并从我的数据库中提取所有数据。虽然这些信息是免费提供的,但我花了很多时间/周/月/年来整理这些信息-这确实是我网站的整个USP。如果有人仅仅通过从服务中提取数据就偷走了我的数据,我会很难过 简单地添加Authorize不会有帮助,因为它可以免费注册 我已经决定,我将在每个请求中向API提交某种令牌,该API将得到验证。基本上,这将是一个已解决的验证码,但它
public class ProductsController : ApiController
{
public IHttpActionResult Get(WebApiToken token, int id)
{
if (token == null)
return BadRequest("Token not supplied");
ITokenValidator requestValidator;
// Some kind of a factory to decide how to validate the token that's been provided.
requestValidator = new GuidTokenValidator();
if (requestValidator.ValidateToken(token))
{
return Ok(string.Format("Some JSON would be returned here representing product ID {0}", id));
}
else
return BadRequest("Token validation failed");
}
}
调用它的Javascript:
<script type="text/javascript">
$(document).ready(function () {
$("#postTest").click(function () {
$.ajax({
type: "GET",
dataType: "json",
url: "/api/Products/2?token=2,OK",
success: function (data) {
alert(data);
},
error: function (error) {
// Error handler
}
});
});
});
</script>
类型转换器:
public class TokenConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, System.Type sourceType)
{
if (sourceType == typeof(string))
{
return true;
}
return base.CanConvertFrom(context, sourceType);
}
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
if (value is string)
{
WebApiToken token;
if (WebApiToken.TryParse((string)value, out token))
{
return token;
}
}
return base.ConvertFrom(context, culture, value);
}
}
小提琴手请求:
GET http://localhost:58106/api/Products/2?token=2,OK HTTP/1.1 Host: localhost:58106 Connection: keep-alive Accept: application/json, text/javascript, */*; q=0.01 X-Requested-With: XMLHttpRequest User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.152 Safari/537.36 Referer: http://localhost:58106/ Accept-Encoding: gzip, deflate, sdch Accept-Language: en-GB,en-US;q=0.8,en;q=0.6
小提琴手的反应:
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?YzpcdXNlcnNcYmVuLnNsb2FuXGRvY3VtZW50c1x2aXN1YWwgc3R1ZGlvIDIwMTNcUHJvamVjdHNcV2ViQVBJQWN0aW9uRmlsdGVyc1xXZWJBUElBY3Rpb25GaWx0ZXJzXGFwaVxQcm9kdWN0c1wy?=
X-Powered-By: ASP.NET
Date: Wed, 20 May 2015 11:59:55 GMT
Content-Length: 60
"Some JSON would be returned here representing product ID 2"
我读到过,发送一个查询字符串来进行身份验证并不是非常RESTful的,他们可能得到的是RESTful URL通常是样式化的。然而,这是为了描述资源,在您的例子中,令牌是上下文信息,因此查询字符串至少在我看来是绝对好的。但是,一种更干净的方法是将令牌作为头发送,这样它就不会影响您的URL,因为令牌实际上与资源不相关。@James感谢您的输入。非常感谢。除了在头中设置令牌外,最好对令牌进行加密。更好的做法是设置OAuth2或更难的东西,让恶意应用程序复制请求。如果您使用的是.NET4.5,请查看OWIN和基于声明的身份验证。
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?YzpcdXNlcnNcYmVuLnNsb2FuXGRvY3VtZW50c1x2aXN1YWwgc3R1ZGlvIDIwMTNcUHJvamVjdHNcV2ViQVBJQWN0aW9uRmlsdGVyc1xXZWJBUElBY3Rpb25GaWx0ZXJzXGFwaVxQcm9kdWN0c1wy?=
X-Powered-By: ASP.NET
Date: Wed, 20 May 2015 11:59:55 GMT
Content-Length: 60
"Some JSON would be returned here representing product ID 2"