检查用户在客户端是否已登录

10

有没有一种安全的方法来检查用户是否已登录应用程序,而不是检查用户机器上是否存在“sid” cookie?

我希望只有在用户已登录时才允许其访问页面上的某些链接。

我在服务器端进行登录验证,但希望避免请求传输。

纯JS或JQuery解决方案将不胜感激。

谢谢。


1
登录到什么? - Jamiec
1
您可以在服务器端验证时创建一个cookie,然后使用jquery在客户端检查该cookie。 - Hemal
感谢您的及时回复。检查sails.js sid会话cookie是否存在于用户中,安全吗? - Me Unagi
https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie - epascarello
7个回答

12

请尝试以下方法

在用户首次登录后添加此代码

jQuery(window).load(function() {
  sessionStorage.setItem('status','loggedIn') 
});

每当用户点击链接时,您可以进行如下检查:

if (sessionStorage.getItem('status') != null))
    //redirect to page
}
else{
    //show validation message
}

4
请注意,会话存储不会在选项卡之间共享。如果用户在“新标签页中打开”,则新标签页将不具有会话存储值。可以使用本地存储作为中介从一个选项卡复制会话存储到另一个选项卡。请参见https://dev59.com/r2Ij5IYBdhLWcg3wYUKR。 - Connell.O'Donnell

4
作为您要求的“安全方式”,不。您应始终在服务器端验证所有请求的用户会话。
但是,您可以根据用户当前状态调整前端。例如,将“登录”链接更改为“注销”链接。为此,您可以在用户计算机上设置某种标志。您可以使用浏览器本地存储进行此操作(http://www.w3schools.com/html/html5_webstorage.asp)。
另外,您可以更改例如链接的行为:
$("a").click(function(e){
    if(localStorage.getItem("isLoggedIn") !== true) {
        e.preventDefault();
        // this prevents navigation and you can now do your js stuff here
    }
});

那个答案应该被接受,因为问题是如何安全地进行检查,而实际上这是不可能的(客户端代码不能被信任;在客户端设置/读取信息,无论是在/从cookie、本地存储等中,都不会改变这一点)。安全模型依赖于客户端执行堆栈(例如浏览器)不被篡改(即安装一个安全的、开源的或可信的浏览器),以及网络堆栈(参见中间人=>https://)。 - chikamichi
我不同意。服务器仍然可以实现检查用户是否已登录,但客户端需要一些状态来判断是否清除其状态并呈现访客视图,还是保持用户视图。 - user823447

3
如果您正在使用ASP.Net Identity,可以按以下方式进行检查:
在Razor视图中:
@inject SignInManager<ApplicationUser> SignInManager

@if (SignInManager.IsSignedIn(User))
        {
            <input type="hidden" id="logged" value="true" />
        }
        else
        {
            <input type="hidden" id="logged" value="false" />
        }

在JS中:

function check() {
var signed = $('#logged').val();

if (signed === 'true') {
    //What you want to do
}
else {
    window.location.href = "/YourController/YourAction?ReturnUrl=/YourReturnUrl;
}
} 

1
解决方案是将此信息作为会话变量(使用php)存储在服务器上,然后使用ajax在javascript中检索此信息。

1
你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心中找到有关如何编写良好答案的更多信息。 - Community

0

我将分享我的客户端验证方法,同时减少对服务器的调用次数。 在我看来,使用会话存储进行验证并不是一个好的方法,因为它不能在选项卡之间共享。

当用户登录您的网站并向服务器发送请求时,请生成一个JWT令牌,有效载荷为其电子邮件ID,并将其作为cookie / json响应发送给客户端。
如果您希望在响应中使用JWT令牌,则将JWT令牌保存在本地存储中,并使用唯一名称(例如myAdminAccessToken)以避免干扰浏览器中的其他键。响应中的cookie比存储JWT令牌更好且更健壮。
现在,每次用户向服务器发出网络请求之前,在进行网络调用(获取URL)之前,请检查本地存储中是否存在令牌。如果不存在,则表示他们未经授权,并将其重定向到登录页面。如果存在,则允许他们向服务器发出网络调用。
解析cookie / JWT令牌并验证电子邮件是否存在,如果存在,则表示他们已获得授权,并在响应中发送authorized:true,让他们从您的服务器获取请求资源。
如果不存在此类电子邮件或JWT令牌解析失败,则表示他们未经授权,并尝试绕过第一步骤中的第一次验证检查。
在这种情况下,请从服务器发送authorized:false响应,并在接收到未经授权的失败后,客户端应将其注销并重定向到登录页面,并从本地存储中删除accessToken。

我没有纯JS或jQuery代码,但如果您想要,我可以与您分享React代码,解释上述过程。

优化

您甚至可以优化以上解决方案,使应用程序更加健壮和安全。

  • 使用Redis缓存用户电子邮件以进行快速验证。
  • 使用状态管理库提供额外的保护层并使您的UI同步。

本地存储、会话存储、状态管理库不可靠,无法保护您的路由/数据,但它们可以用于减少对服务器的网络调用次数。


0
在我看来,你应该将一个带有过期日期的authToken保存到本地存储中,然后每次请求时(不包括GET),检查它是否已过期,并与服务器验证authToken是否已过期。这是双重验证。
客户端到客户端和客户端到服务器。两者都应正确匹配。

0

它应该百分之百地工作

在用户登录页面(登录页面的下一页)之后放置此代码

jQuery(window).load(function() {
  sessionStorage.setItem('status','loggedIn') 
 });

每当用户点击链接时,您可以使用以下代码检查任何页面(任何页面)

if (sessionStorage.getItem('status') != null){
//redirect to page
alert("Is Login : True");
 }
 else{
  //show validation message
 alert("Is Login : False");
 }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接