Angular、.NET Web Api 验证(Authentication)与跨来源资源共享(Cors)

验证是任何 Web 服务都必须考虑的基础问题。关于 .NET 平台的验证与授权,按理说微软已经提供了相当充分的文档与示例代码。

.NET Identity 框架提供了现成的数据库结构以及一系列接口,可以实现用户注册、登录登出、口令生成、邮箱的确认、密码重置等基本功能,也可以与社交媒体账户集成实现用户注册与登陆。

需要注意的是,.NET MVC 与 .NET Core 所使用的接口代码和 .NET Web Api 有所不同,如果混合阅读文档与代码,可能会造成混淆与理解上的困扰。不同版本的文档对邮箱验证等功能的处理逻辑也有差别,不可简单合并使用。

后端若部署至 Azure 等云平台,口令的生成也可能会遇到在本地不会发生的问题,报错“ The data protection operation was unsuccessful. This may have been caused by not having the user profile loaded for the current thread’s user context, which may be the case when the thread is impersonating.”。例如,.NET MVC 版示例代码在用户登录并验证邮箱后生成口令时会试图调用 /Token 接口,触发错误。网上针对此问题有一些解决方案,却都不太有效。事实上,可暂时忽略对邮箱是否得到验证的检查,直接前台调用 /Token 接口,就能避免该错误。对邮箱的确认可以在之后实际执行处理时按需进行。

微软官方的示例代码都没有涉及 Cors(cross origin resource sharing) 问题,即使是 Angular 项目模板,由于前端默认与后端共存于同一个解决方案,也不存在这一问题。然而,如果前后端分离,前端 Angular 程序的域名很可能与后端不同。

微软针对 .NET Web Api 的 Cors 有一些文档,但很遗憾,如果有接口通过 bearer token 进行验证与授权,那些文档中的解决方案很可能会引发新的问题。

  • .NET Web Api 中对 允许跨源访问:介绍多种允许 Cross origin request 的方式

由于 Chrome 等一些浏览器在一定条件下出于安全原因为首先发送 OPTIONS method 的 HTTP 请求(如 headers 中指定 “Content-Type”: “application/x-www-form-urlencoded” 时),情况变得更加复杂。

如果 OPTIONS method 没有被允许,则会遇到 405 错误代码。不当的设置可能会在允许跨源访问资源时却阻碍了用户登录等验证 API。又或是无意中重复允许 Cors origin 设置,会提示 The ‘Access-Control-Allow-Origin’ header contains multiple values 错误而无法获得资源。

网络上简单明了且实际有效的解决方案并不好找,经过反复尝试与分析,要避免所有这类问题,采用全局设置恐怕是最简单的方法之一。

  • 不要像下面这样通过 Web.config 来设置 Cors

  • 不要像下面这样通过 ApiController 属性来设置 Cors

  • 不要再 WebApiConfig 等类中通过诸如 config.EnableCors(); 等代码方式设置 Cors
  • 安装 Microsoft.Owin.Cors 的 NuGet 包
  • 在 startup.cs 的 ConfigureAuth 方法开始时调用语句 app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
  • Angular 前端发送请求时, headers 中只需指定 “Content-Type”: “application/x-www-form-urlencoded” 一项即可
  • 如果使用 RestAngular 获取资源,只需按如下方式设置 Content-Type 与 Authorization 即可

 

至此,运行于 Azure App Service 的后端 .NET Web Api 将可以与非同源的 Angular 程序交互,实现本地用户账号的注册登陆等操作,可以通过 bearer token 实现资源请求过程中的验证与授权。

尝试 Angular

之前做过一些 AngularJS 的小型项目,用的工具和流程却大多是过时的一套,大半精力也仍花费在后台业务逻辑。时至今日虽然晚了一些,打算跟上时代,尝试一下 Angular 的开发。

有几个关注点:

  • 以 Angular 4 入手,系统学习 Angular 框架的概念与机制
  • 完全的前后端分离
  • 使用 Angular CLI 创建模板
  • 借助 VSTS 管理项目代码与发布
  • Angular 部分完全使用 VS Code 开发

Angular 4 并不是最新版本,大版本升级的周期是每6个月,但从 Angular 2 起每个大版本都能基本兼容,Angular 4 的文档也相对丰富,故选择从这里开始。完全前后端分离可以更高效分工,带来一系列好处,如提高团队合作效率。而 Angular CLI 几乎已经成为默认的选项,这次也打算应用。至于 VSTS,最近的项目经历感觉没有最大程度发挥其价值,所以希望在也与项目中进一步探索其可能性。VS Code 虽已成为自己的常用工具,但能否完全担当起开发之职,也会是这次的一个课题。

起动步骤极为简单。

在安装 Node.js 后,通过命令行安装 Angular CLI:

CD 定位至希望的文件夹后,新建 Angular 项目:

运行新建的项目,并以 open 选项打开浏览器页面,默认端口为4200:

此时,通过 VS Code 对代码做任何修改并保存后都会立即体现在程序上。

至此,尝试 Angular 的第一步已经踏出。今后将不定期更新心得感想。