Web Api 2-检查用户是否已登录



我仍然在ASP.NET中找到自己的路。

我正在尝试让Angular代码与Web API 2端点对话,该端点只能从解决方案本身中访问。

我想做的一件事是根据当前用户是匿名登录还是浏览来显示或隐藏编辑按钮。

我可以在MVC视图中通过检查User.Identity.IsAuthenticated来实现这一点,但我很好奇如何在没有.NET编码的情况下使用纯Angular页面来实现

我想我可以做一些类似的事情

public class AuthorizationController : ApiController
{
public HttpResponseMessage Get()
{
if (User.Identity.IsAuthenticated)
{
return Request.CreateResponse(HttpStatusCode.OK, "Ok");
}
else
{
return Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "You are not authorized");
}
};
}

然后把它叫做

$http.get("../api/authorization")
.then(function (response) 
{
if(response.status=="200") 
{
// logged in
}
else
{
// not logged in
}
});

不幸的是,这并没有达到我的期望。如果用户没有登录,API代码会点击创建错误响应的行,但它实际返回到Angular回调的是

{"data":"<!DOCTYPE html>rn<html>rn<head>rn <meta charset="utf-8" />rn <meta name="viewport" content="width=device-width, initial-scale=1.0">rn <title>Log in - My ASP.NET Application</title>rn <link href="/Content/bootstrap.css" rel="stylesheet"/>rn<link href="/Content/site.css" rel="stylesheet"/>rnrn <script src="/Scripts/modernizr-2.6.2.js"></script>rnrnrn</head>rn<body>rn <div class="navbar navbar-inverse navbar-fixed-top">rn <div class="container">rn <div class="navbar-header">rn <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">rn <span class="icon-bar"></span>rn <span class="icon-bar"></span>rn <span class="icon-bar"></span>rn </button>rn <a class="navbar-brand" href="/">Application name</a>rn </div>rn <div class="navbar-collapse collapse">rn <ul class="nav navbar-nav">rn <li><a href="/">Home</a></li>rn <li><a href="/Home/About">About</a></li>rn <li><a href="/Home/Contact">Contact</a></li>rn </ul>rn <ul class="nav navbar-nav navbar-right">rn <li><a href="/Account/Register" id="registerLink">Register</a></li>rn <li><a href="/Account/Login" id="loginLink">Log in</a></li>rn </ul>rnrn </div>rn </div>rn </div>rn <div class="container body-content">rn rnrnrn<h2>Log in.</h2>rn<div class="row">rn <div class="col-md-8">rn <section id="loginForm">rn<form action="/Account/Login?ReturnUrl=%2Fapi%2Fauthorization" class="form-horizontal" method="post" role="form"><input name="__RequestVerificationToken" type="hidden" value="5h-wFJ5pn4Vq8uI15BbzTvAwAFuudI1jaF_YsHfpAp9YFaeArEkO4P6i5bFMYgSs6OY6BXDEHzNLFpxYA-IvQJlr7zYY8Bgj9mErF1dgMQQ1" /> <h4>Use a local account to log in.</h4>rn <hr />rn <div class="form-group">rn <label class="col-md-2 control-label" for="Email">Email</label>rn <div class="col-md-10">rn <input class="form-control" data-val="true" data-val-email="The Email field is not a valid e-mail address." data-val-required="The Email field is required." id="Email" name="Email" type="text" value="" />rn <span class="field-validation-valid text-danger" data-valmsg-for="Email" data-valmsg-replace="true"></span>rn </div>rn </div>rn <div class="form-group">rn <label class="col-md-2 control-label" for="Password">Password</label>rn <div class="col-md-10">rn <input class="form-control" data-val="true" data-val-required="The Password field is required." id="Password" name="Password" type="password" />rn <span class="field-validation-valid text-danger" data-valmsg-for="Password" data-valmsg-replace="true"></span>rn </div>rn </div>rn <div class="form-group">rn <div class="col-md-offset-2 col-md-10">rn <div class="checkbox">rn <input data-val="true" data-val-required="The Remember me? field is required." id="RememberMe" name="RememberMe" type="checkbox" value="true" /><input name="RememberMe" type="hidden" value="false" />rn <label for="RememberMe">Remember me?</label>rn </div>rn </div>rn </div>rn <div class="form-group">rn <div class="col-md-offset-2 col-md-10">rn <input type="submit" value="Log in" class="btn btn-default" />rn </div>rn </div>rn <p>rn <a href="/Account/Register">Register as a new user</a>rn </p>rn</form> </section>rn </div>rn <div class="col-md-4">rn <section id="socialLoginForm">rn rn<h4>Use another service to log in.</h4>rn<hr />rn <div>rn <p>rn There are no external authentication services configured. See <a href="http://go.microsoft.com/fwlink/?LinkId=403804">this article</a>rn for details on setting up this ASP.NET application to support logging in via external services.rn </p>rn </div>rnrnrn </section>rn </div>rn</div>rnrnrn <hr />rn <footer>rn <p>&copy; 2016 - My ASP.NET Application</p>rn </footer>rn </div>rnrn <script src="/Scripts/jquery-2.2.3.js"></script>rnrn <script src="/Scripts/bootstrap.js"></script>rn<script src="/Scripts/respond.js"></script>rnrn rn <script src="/Scripts/jquery.validate.js"></script>rn<script src="/Scripts/jquery.validate.unobtrusive.js"></script>rnrnrnrn<!-- Visual Studio Browser Link -->rn<script type="application/json" id="__browserLink_initializationData">rn {"appName":"Firefox","requestId":"69b5785bb7f0400088c465aa19c19c8a"}rn</script>rn<script type="text/javascript" src="http://localhost:55784/9f4b9571f5a149d8a3ad956c641aff65/browserLink" async="async"></script>rn<!-- End Browser Link -->rnrn</body>rn</html>rn","status":200,"config":{"method":"GET","transformRequest":[null],"transformResponse":[null],"url":"../api/authorization","headers":{"Accept":"application/json, text/plain, */*"}},"statusText":"OK"} 

所以它似乎在返回一个登录页面。有人能告诉我我做错了什么吗?还是我用这种方法完全搞错了?

假设您使用的是表单身份验证。默认情况下,表单身份验证将检测管道中的未经身份验证的事件(401),并将其转换为重定向(302)到登录页面。如果你的客户端自动遵循重定向(大多数都这样做),那么你最终会得到登录页面的内容,其中包含HTTP成功状态代码(200)。

对此有两种相当直接的解决方案:

  1. 不要使用表单身份验证(好吧,如果手头没有替代的身份验证中间件,就不完全是直接的)
  2. HttpResponse.SuppressFormsAuthenticationRedirect属性设置为true

根据HttpResponse.SuppressFormsAuthenticationRedirect:的文档

默认情况下,表单身份验证将HTTP 401状态代码转换为302以便重定向到登录页面。这不适合某些类别的错误,例如身份验证成功但授权失败,或者当前请求是AJAX或web时服务请求。此属性提供了一种抑制重定向的方法行为,并将原始状态代码发送给客户端。

关于属性的值:

true如果表单身份验证重定向应被抑制;否则,false

要进一步阅读,并完全归功于Phil Haack是我第一个获得该主题简单信息的来源,请查看他关于该主题的博客文章。

我知道问题是关于服务器端web api的
但如果有人想研究另一种方法,
并且可以使用javascript/typescript在客户端执行
,也许这种方法可以帮助未来的读者:

我更喜欢使用localStorage在本地执行,并节省对服务器的不必要调用
this.serverResponse.expires_in是以秒为单位的过期时间。

从web api服务器提取到期日期:

var tokenexpiration: Date = new Date();
tokenexpiration.setSeconds(new Date().getSeconds() + parseInt(this.serverResponse.expires_in))
console.log(tokenexpiration);

您可以将其保存到本地存储:

localStorage.setItem('expirationdate',tokenexpiration)

通过简单的条件,您可以随时检查令牌是否已过期。

您应该了解AuthorizeAttribute。您可以用它或它的一些方法装饰您的控制器,然后在AngularJS中处理UnAuthorized异常(我认为状态为401)。

.Net在大多数情况下会根据cookie来决定请求是否得到授权,但这实际上取决于您使用的身份验证方案。

最新更新