使用Web API来构建Web 服务,是一件非常容易的事情。Web API使用Http协议, 具备良好的可访问性,尤其适于部署到internet.
作为服务,就有一个版本化和安全的问题。 下面分两块说明。
1. 版本化
1) 最简单的方式,变更url
/api/accountv1
/api/accountv2
2) 利用url segment的方式
/api/v2/account
3) 利用request header
/api/account
api-version: 2
4) 使用content type
/api/account
Accept: application/vnd.haveibeenpwned+json; version=2.0
或者
Accept: application/vnd.haveibeenpwned.v2+json
5) 使用url参数的方式
/api/account?version=2
一些知名公司采用的版本化方案:How are REST APIs versioned?
实现多种版本方式的API例子:https://haveibeenpwned.com/API/v2
在Asp.Net WebAPI 2.0 启用AttributeRouting, 结合自定义RouteAttribute和RouteConstraint,很容易实现版本化。
如果是WebAPI 1.0升级到2.0, 注意修改注册代码:
protected void Application_Start()
{
// WARNING - Not compatible with attribute routing.
WebApiConfig.Register(GlobalConfiguration.Configuration);
}
WebAPI 2.0中:
protected void Application_Start()
{
// Pass a delegate to the Configure method.
GlobalConfiguration.Configure(WebApiConfig.Register);
}
注册路由按照下面的顺序,
首先WebAPI
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Attribute routing.
config.MapHttpAttributeRoutes();
// Convention-based routing.
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
然后MVC
public static void RegisterRoutes(RouteCollection routes)
{
// Ignore
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// Attribute routing
routes.MapMvcAttributeRoutes();
// Convention-based routing.
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
Global代码模板:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
// WARNING - Not compatible with attribute routing.
//WebApiConfig.Register(GlobalConfiguration.Configuration);
// -> Pass a delegate to the Configure method.
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
// WebAPI remove xml formater
GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
}
Debug结果
参考资料
1) Achieving versioning with Web API in ASP.NET MVC (使用url segment, 通过不同名称的Controller实现)
2) Looking at ASP.NET MVC 5.1 and Web API 2.1 - Part 2 - Attribute Routing with Custom Constraints (使用AttributeRouting定制路由)
3) Web API 版本化的介绍 (后端实现自定义Controller选择器,从request header, content type等地方获取版本信息,然后实例化特定controller)
4) Attribute Routing in ASP.NET MVC 5
5) Attribute Routing in ASP.NET Web API 2
2. 安全性
安全性涉及范围特别广泛, 这里要说的是Web API的合法调用。为了考虑各种客户端的调用,采用的实现方案如下:
1) 调用端需要集中注册,获取AppId和密钥
2) 客户端调用的时候,需要采用约定的加密算法,根据AppId, 时间,随机数等,算出一个token, 添加到http header中
3) 服务器收到请求后,解密token, 并检查是否访问是否过期
其它的安全性措施包括:
1)建议client的调用从服务器端发起。如果要从js端发起,则需要预先token,并且设置较短的过期时间
2) 传输的安全性使用Https
3) API提供端可以通过Filter机制,强制访问使用https, 并且可配置限定IP才能访问
参考资料
2) Making your ASP.NET Web API’s secure
其它关于Web API的参考资料:
1) Detailed Tutorial for Building ASP.Net Web API RESTful Service (中文翻译)