Angular 如何在单页应用程序中使用ColdFusion会话管理?

Angular 如何在单页应用程序中使用ColdFusion会话管理?,angular,session-cookies,coldfusion-11,session-management,Angular,Session Cookies,Coldfusion 11,Session Management,我有一个Angular 4 SPA(单页应用程序),由一个服务器提供服务,该服务器上有ColdFusion 11。我正在通过AJAX调用使用ColdFusion服务器上.CFC文件中包含的许多函数 我希望发生以下情况: 用户进入my Angular 4应用程序的页面(myapp.mydomain.com),并将被重定向到登录屏幕(myapp.mydomain.com/login),在其中输入用户名和密码。Angular 4应用程序将调用服务器上的.CFC来验证其登录信息。.CFC将返回“是”或“

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

我希望发生以下情况:

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

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

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

基本上,我需要保护客户端(在Angular 4中使用Auth Guard样式的服务,我知道如何做)和服务器端(使用ColdFusion 11会话管理,我不知道如何做),并且我需要它们不断地就两者的授权状态进行通信,无需每次都询问会话是否仍然有效。(Angular 4应用程序是否可以读取ColdFusion会话cookies?)

我怎样才能让这两个东西像那样相互配合呢?还是我对ColdFusion会话管理的无知让我对一个我还没有想到的更好的解决方案视而不见


如有任何建议,我们将不胜感激。谢谢

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

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

  • 客户端必须发出一个路由到ColdFusion的请求(即,它点击的是
    cfc
    cfm
    ,而不是一些静态html或js)
  • 在请求的
    cfm
    /
    cfc
    所在目录的同一目录或某个祖先目录中必须存在
    Application.cfc
  • Application.cfc
    必须使用
    this.sessionmanagement=true启用会话变量
当满足这些条件时,ColdFusion将请求与会话相关联。有3种方式可以建立此关联:

  • 客户端已经有有效的会话cookie,并在请求中发送它们。您的CFML代码可以读取在以前的请求中创建的会话变量,并为将来的请求设置要读取的新值
  • 客户端是新的,没有cookie。ColdFusion创建一组新的cookie和一个新的会话范围。您的CFML代码可以为将来的读取请求设置会话变量。新的cookies将与您的响应一起自动发送到客户端
  • 客户端发送cookie,但它们对应于过期的会话。这与前一个案例一样处理。将发送新cookie,并且存在一个空会话作用域供您的CFML填充
在客户端上,ajax请求也不能免除Cookie的限制

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

大多数情况下,您只使用会话变量,而不考虑cookies或它们是如何到达那里的

因此,对于您的用例,如果您的
login
页面在内部路由到
login.cfm
,并且附近有一个
Application.cfc
,会话范围就可以在
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...
}
您的
注销
代码可以
StructDelete(会话,“用户”)

在其他任何地方,在您所有的
cfc
cfm
中,请求是否来自登录用户的问题很简单:如果客户端以前登录过,并且会话尚未过期,则存在
session.user
。否则它不会(您将有一个会话—始终存在一个会话,因为ColdFusion在运行CFML代码之前创建了一个会话—但在您将一个会话放入其中之前,它不会有
user
变量)

您也可以在登录请求中设置其他与用户相关的变量(并在注销时取消设置),如实名、首选项、要从数据库加载的任何经常使用和不经常更新的内容,您可以将其保留在会话范围内。另外还有
cflogin
,它应该有助于管理用户登录,但似乎没有必要。(见附件)

你想避免“每次都要问”的愿望并没有真正实现,但“问”是最低限度的。客户端在每个ajax请求中发送cookie,这实际上是在“请求”会话继续。它必须检查每个ajax响应是否存在“会话超时”错误。在服务器上,每个请求处理函数都必须首先检查会话变量是否存在

但是您可以在客户机上使用ajax包装器来减轻痛苦


在服务器上,您可以使用一个
onRequestStart
为所有请求提供一个通用的“预检查”,这样您甚至不需要在每个函数的顶部都有
if(…无用户…{返回“哦,不”;}

我对coldfusion方面的了解比对angular方面的了解更多(比如,我从来没有看过angular)。试图理解这个问题。。。所有ajax请求都是到coldfusion服务器的,对吗?因此,每个远程可访问的cfc函数都以
开头,如果(!IsDefined(“session.user”))返回{some