【问题标题】:How to check ASP.NET Forms Authentication Status Using Only JavaScript?如何仅使用 JavaScript 检查 ASP.NET 表单身份验证状态?
【发布时间】:2011-03-18 06:10:43
【问题描述】:

我需要这样做的原因是因为 Facebook 连接 - 这是另一个故事,所以我会为你节省剧情。 =)

无论如何,我有这个在 window.onload 上运行的函数:

function userAuth() {
   SomeFunctionWhichGetsFacebookCookes();
   if (!loggedInUsingFormsAuth && loggedInViaFacebook) {
     window.location.reload(); // refresh page, so i can perform auto-login
   }
}

所以,我需要帮助来获取“loggedInUsingFormsAuth”标志。

我不关心cookie中的内容,只需要知道当前用户是否经过身份验证。

我为什么要这样做?

好吧,在窗口加载时,如果用户登录 Facebook 但未登录我的网站(根据表单身份验证 cookie),我想重新加载页面 - 这允许我的 ASP.NET 网站读取 Facebook cookie HttpContext 并让用户登录。我需要在 JavaScript 中执行此操作,因为在我调用“SomeFunctionWhichGetsFacebookCookies”之前我没有 Facebook cookie - 这只能在 JavaScript 中完成。

那么,我如何判断当前用户是否通过 JavaScript 进行了身份验证?我是否必须手动遍历 cookie,找到我想要的并检查它?这样做安全吗?

或者我是否应该使用 RegisterClientScript 将标志从服务器写入客户端?

【问题讨论】:

  • 最终将 HttpContext.Current.Request.IsAuthenticated 属性注册到客户端以供 JavaScript 使用。更容易。

标签: javascript asp.net cookies forms-authentication


【解决方案1】:

您可以将以下内容添加到您的 web.config 文件中。

<system.web.extensions>
     <scripting>
    <webServices>
         <!-- Allows for ajax.net user authentication -->
         <authenticationService enabled="true" requireSSL="false" />
    </webServices>
     </scripting>
</system.web.extensions>

然后您可以通过 javascript 了解您是否已通过身份验证 像这样。

function isAuth() {
    var result = Sys.Services.AuthenticationService.get_isLoggedIn();
    return result;
}

【讨论】:

  • 有趣,但它仍在后台调用服务器。
【解决方案2】:

比您在评论中描述的更好的方法是创建一个简单的 Web 服务,您可以调用该服务来检索值。

【讨论】:

  • 然后我需要额外调用服务器,这是我不想要的。我在 Page_PreRender 上渲染了 javascript,现在我只是用来自服务器的值渲染它。
  • 对服务器的调用是实时的,检查 javascript 变量会告诉您用户已登录,而实际上他们的会话已过期。
  • 理论上,你是对的——但实际上我在页面加载时注册了 javascript,然后立即在同一个 javascript 中检查 cookie——换句话说,实时(页面加载,检查身份验证,在javascript中设置身份验证,javascript立即运行并检查身份验证)。无论如何感谢您的回答。
【解决方案3】:

当我在每次页面加载时通过服务器注册 JavaScript 时,我决定将 HttpContext.Current.Request.IsAuthenticated 属性设置为 JavaScript 本身。

换句话说,我在 C# 本身中定义了一些 JavaScript:

public class SomeClassWhichHasAccessToHttpContext
{
   private const string MyScript = "var foo='{0}'";

   public static string GetMyScript()
   {
      return string.Format(MyScript, HttpContext.Current.Request.IsAuthenticated);
   }
}

然后在我的主页的 HTML 上:

<%= SomeClassWhichHasAcccessToHttpContext.GetMyScript() =>

通常我不会选择这样的解决方案,我通常会调用异步 Web 服务(正如 Ben 的回答中提到的那样)。但事实是这个属性和 JavaScript 是在页面请求的基础上评估的,所以对于每个给定的 HTTP 请求,这个属性的评估永远不会过时。

【讨论】:

    【解决方案4】:

    我有一个只需要在一个地方编写代码的解决方案:

    将以下代码添加到 Global.asax.cs

        protected void Application_EndRequest(object sender, EventArgs e)
        {           
            try
            {
                System.Web.UI.Page P = (System.Web.UI.Page)HttpContext.Current.Handler;//will throw error if request is not for a page
                if (P.IsCallback) { return; }
                if (P.IsPostBack)
                {
                    try
                    {
                        //if using AjaxControlToolKit and UpdatePanels
                        if (AjaxControlToolkit.ToolkitScriptManager.GetCurrent(P).IsInAsyncPostBack)
                        {
                            //Async postback caused by update panel           
                            return;
                        }
                    }
                    catch (Exception)
                    { 
                       //will throw error if no scriptmanager- which doesn't matter
                    } 
                }
                //skip this part if not using AjaxControlToolkit or if you have it set up to get scripts from a web handler: http://blogs.msdn.com/b/delay/archive/2007/06/20/script-combining-made-better-overview-of-improvements-to-the-ajax-control-toolkit-s-toolkitscriptmanager.aspx                   
                foreach (string key in P.Request.QueryString)
                {
                    //request is from AjaxControlToolkit to get scripts. Don't want to mess with the response for this
                    if (key.ToLower().Contains("TSM"))
                    {
                        if(P.Request.QueryString[key].ToLower().Contains("toolkitscriptmanager"))
                        return;
                    }
                }
                //dont want to inject this when a page is outputting a file
                if (Response.ContentType != "text/html") { return; }
    
                //still going: request is for a page and its a first load or a full page postback
                Response.Write(" <script> try{ window.UserLoggedIn=" + HttpContext.Current.User.Identity.IsAuthenticated.ToString().ToLower()+ ";} catch(ex){} </script> ");
            }
            catch (Exception)
            {
    
            }
        }
    

    现在客户端变量 UserLoggedIn 在每个页面上都可用。

    【讨论】:

      猜你喜欢
      • 2014-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多