如何将ColdFusion会话管理与单页应用程序一起使用?

时间:2017-07-13 23:14:33

标签: angular session-cookies coldfusion-11 session-management

我有一个Angular 4 SPA(单页应用程序)由服务器提供服务,其上有ColdFusion 11。我正在通过AJAX调用使用ColdFusion服务器上的.CFC文件中包含的许多函数。

我希望发生以下情况:

用户访问我的Angular 4应用程序页面(myapp.mydomain.com),并将重定向到登录屏幕(myapp.mydomain.com/login),他们将在其中输入用户名和密码。然后,Angular 4应用程序将调用服务器上的.CFC以验证其登录信息。 .CFC将返回“是”或“否”验证信息。然后Angular 4应用程序将它们重定向到myapp.mydomain.com/home(或者我希望它们去的任何地方)。

同时,我希望ColdFusion为该用户创建一个新会话 - 这样,如果会话超时,或者用户注销,任何其他.CFC的任何进一步调用都将被拒绝。

如果ColdFusion会话超时,我希望Angular 4应用程序注意到这一点并将用户重定向到/ login路由。

基本上我需要保护客户端(使用Angular 4中的Auth-Guard样式服务,我知道该怎么做)和服务器端(使用ColdFusion 11会话管理,我不知道该怎么办),我需要他们不断地就两者的授权状态进行沟通,而不必询问每个 时间是否会话仍然有效。 (Angular 4 app可以以某种方式读取ColdFusion会话cookie吗?)

我如何让这两件事情相互合作呢?或者我对ColdFusion会话管理的无知使我陷入了一个更好的解决方案,我还没有想到呢?

任何建议都表示赞赏。谢谢!

1 个答案:

答案 0 :(得分:1)

在服务器上,cfc不能免于自动会话创建和cookie管理

对于有权访问会话变量的请求,必须满足以下条件:

  • 客户端必须发出路由到ColdFusion的请求(即它命中cfccfm,而不是某些静态html或js)。
  • 请求的Application.cfc / cfm所在的目录或某个祖先目录中必须有cfc
  • Application.cfc必须使用this.sessionmanagement = true;
  • 启用会话变量

当满足这些条件时,ColdFusion会将请求与会话相关联。我可以通过3种方式建立这种联系:

  • 客户端已经拥有有效的会话cookie并在请求中发送它们。您的CFML代码可以读取在先前请求中创建的会话变量,并为将来要读取的请求设置新值。
  • 客户端是新的,没有cookie。 ColdFusion创建一组新的cookie和一个新的会话范围。您的CFML代码可以设置会话变量以供将来的读取请求使用。新的Cookie会随您的回复一起自动发送给客户。
  • 客户端发送cookie,但它们对应于过期的会话。这与前一种情况一样处理。发送新的cookie并且存在空的会话范围以供CFML填充。

在客户端上,ajax请求不能免于cookie

底层XMLHttpRequest从与所有其他请求相同的cookie存储中获取和设置cookie。如果请求的URL与cookie的域,路径,安全标志匹配,则XMLHttpRequest将发送cookie。如果它在响应中获得有效的cookie,它将添加它们。

大多数情况下,您只使用会话变量而不考虑Cookie或它们是如何实现的

因此,对于您的使用案例,如果您的login页面内部路由到login.cfm,并且附近有Application.cfc,则会话范围已准备好供您尽快使用{ {1}}开始。你可以做到

login.cfm

您的if(IsDefined("form.username") && IsDefined("form.password")) { if(...check password [aka the hard part]...) { session.user = form.username; location(url="/home"); } else { location(url="/login"); } } else { ...print the login form... } 代码可以logout

在其他任何地方,在您的StructDelete(session, "user")cfc中,请求来自登录用户的问题很简单:如果客户端先前已登录,则会话尚未过期,则cfm存在。否则它没有(你将有一个会话 - 总有一个会话,因为ColdFusion在运行你的CFML代码之前创建了一个 - 但是在你把它放在那里之前不会有session.user变量。

您也可以在登录请求中设置其他与用户相关的变量(并在注销时取消设置),例如实名,首选项,您想要从经常使用且不经常更新的数据库加载的任何内容,您可以保留在会话范围内。还有user这应该有助于管理用户登录,但似乎没有必要。 (见Why don't people use <CFLOGIN>?

你想避免“不得不每时每刻都要问”的愿望并没有真正实现,但“要求”是微不足道的。客户端在每个ajax请求中发送cookie,这有效地“要求”继续会话。并且它必须检查每个ajax响应的“会话超时”错误。在服务器上,每个请求处理函数都必须以检查是否存在会话变量开始。

但是你可以在客户端上使用ajax包装来减轻痛苦。

在服务器上,您可以使用cflogin为所有请求提供常见的“预先检查”,这样您甚至不需要在每个函数的顶部都有onRequestStart