我仍然在ASP.NET中找到了解决方法。
我正在尝试让Angular代码与Web API 2端点进行通信,只能从解决方案本身访问它。
我希望能够做的一件事是根据当前用户是登录还是匿名浏览来显示或隐藏编辑按钮。
我可以通过检查User.Identity.IsAuthenticated
在MVC视图中执行此操作,但我很好奇我如何使用纯Angular页面进行此操作,其中没有.NET编码。
我以为我可以做这样的事情
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>\r\n<html>\r\n<head>\r\n <meta charset=\"utf-8\" />\r\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n <title>Log in - My ASP.NET Application</title>\r\n <link href=\"/Content/bootstrap.css\" rel=\"stylesheet\"/>\r\n<link href=\"/Content/site.css\" rel=\"stylesheet\"/>\r\n\r\n <script src=\"/Scripts/modernizr-2.6.2.js\"></script>\r\n\r\n\r\n</head>\r\n<body>\r\n <div class=\"navbar navbar-inverse navbar-fixed-top\">\r\n <div class=\"container\">\r\n <div class=\"navbar-header\">\r\n <button type=\"button\" class=\"navbar-toggle\" data-toggle=\"collapse\" data-target=\".navbar-collapse\">\r\n <span class=\"icon-bar\"></span>\r\n <span class=\"icon-bar\"></span>\r\n <span class=\"icon-bar\"></span>\r\n </button>\r\n <a class=\"navbar-brand\" href=\"/\">Application name</a>\r\n </div>\r\n <div class=\"navbar-collapse collapse\">\r\n <ul class=\"nav navbar-nav\">\r\n <li><a href=\"/\">Home</a></li>\r\n <li><a href=\"/Home/About\">About</a></li>\r\n <li><a href=\"/Home/Contact\">Contact</a></li>\r\n </ul>\r\n <ul class=\"nav navbar-nav navbar-right\">\r\n <li><a href=\"/Account/Register\" id=\"registerLink\">Register</a></li>\r\n <li><a href=\"/Account/Login\" id=\"loginLink\">Log in</a></li>\r\n </ul>\r\n\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"container body-content\">\r\n \r\n\r\n\r\n<h2>Log in.</h2>\r\n<div class=\"row\">\r\n <div class=\"col-md-8\">\r\n <section id=\"loginForm\">\r\n<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>\r\n <hr />\r\n <div class=\"form-group\">\r\n <label class=\"col-md-2 control-label\" for=\"Email\">Email</label>\r\n <div class=\"col-md-10\">\r\n <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=\"\" />\r\n <span class=\"field-validation-valid text-danger\" data-valmsg-for=\"Email\" data-valmsg-replace=\"true\"></span>\r\n </div>\r\n </div>\r\n <div class=\"form-group\">\r\n <label class=\"col-md-2 control-label\" for=\"Password\">Password</label>\r\n <div class=\"col-md-10\">\r\n <input class=\"form-control\" data-val=\"true\" data-val-required=\"The Password field is required.\" id=\"Password\" name=\"Password\" type=\"password\" />\r\n <span class=\"field-validation-valid text-danger\" data-valmsg-for=\"Password\" data-valmsg-replace=\"true\"></span>\r\n </div>\r\n </div>\r\n <div class=\"form-group\">\r\n <div class=\"col-md-offset-2 col-md-10\">\r\n <div class=\"checkbox\">\r\n <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\" />\r\n <label for=\"RememberMe\">Remember me?</label>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"form-group\">\r\n <div class=\"col-md-offset-2 col-md-10\">\r\n <input type=\"submit\" value=\"Log in\" class=\"btn btn-default\" />\r\n </div>\r\n </div>\r\n <p>\r\n <a href=\"/Account/Register\">Register as a new user</a>\r\n </p>\r\n</form> </section>\r\n </div>\r\n <div class=\"col-md-4\">\r\n <section id=\"socialLoginForm\">\r\n \r\n<h4>Use another service to log in.</h4>\r\n<hr />\r\n <div>\r\n <p>\r\n There are no external authentication services configured. See <a href=\"http://go.microsoft.com/fwlink/?LinkId=403804\">this article</a>\r\n for details on setting up this ASP.NET application to support logging in via external services.\r\n </p>\r\n </div>\r\n\r\n\r\n </section>\r\n </div>\r\n</div>\r\n\r\n\r\n <hr />\r\n <footer>\r\n <p>© 2016 - My ASP.NET Application</p>\r\n </footer>\r\n </div>\r\n\r\n <script src=\"/Scripts/jquery-2.2.3.js\"></script>\r\n\r\n <script src=\"/Scripts/bootstrap.js\"></script>\r\n<script src=\"/Scripts/respond.js\"></script>\r\n\r\n \r\n <script src=\"/Scripts/jquery.validate.js\"></script>\r\n<script src=\"/Scripts/jquery.validate.unobtrusive.js\"></script>\r\n\r\n\r\n\r\n<!-- Visual Studio Browser Link -->\r\n<script type=\"application/json\" id=\"__browserLink_initializationData\">\r\n {\"appName\":\"Firefox\",\"requestId\":\"69b5785bb7f0400088c465aa19c19c8a\"}\r\n</script>\r\n<script type=\"text/javascript\" src=\"http://localhost:55784/9f4b9571f5a149d8a3ad956c641aff65/browserLink\" async=\"async\"></script>\r\n<!-- End Browser Link -->\r\n\r\n</body>\r\n</html>\r\n","status":200,"config":{"method":"GET","transformRequest":[null],"transformResponse":[null],"url":"../api/authorization","headers":{"Accept":"application/json, text/plain, */*"}},"statusText":"OK"}
所以它似乎正在返回登录页面。有人能告诉我我做错了什么吗?或者我只是用这种方法完全咆哮错误的树?
答案 0 :(得分:2)
我知道问题出在服务器端Web api上。
,但是如果有人想研究另一种方法,
并且可以在客户端使用javascript / typescript
也许这种方法可以帮助将来的读者:
我更喜欢在本地使用localStorage进行操作,并将不必要的调用保存到服务器。
{
"key": "ctrl+shift+c",
"command": "multiCommand.terminateTerminal"
// "when": "editorTextFocus"
},
是有效时间,以秒为单位。
从Web api服务器中提取到期日期:
this.serverResponse.expires_in
可以将其保存到localStorage:
var tokenexpiration: Date = new Date();
tokenexpiration.setSeconds(new Date().getSeconds() + parseInt(this.serverResponse.expires_in))
console.log(tokenexpiration);
而且条件简单,您可以随时检查令牌是否已过期。
答案 1 :(得分:1)
据推测,您正在使用表单身份验证。默认情况下,表单身份验证将检测管道中的未经身份验证的事件(401)并将其转换为重定向(302)到登录页面。如果您的客户端自动遵循该重定向(大部分都是),那么您最终将获得具有HTTP成功状态代码(200)的登录页面的内容。
有两个相当直接的解决方案:
HttpResponse.SuppressFormsAuthenticationRedirect
属性设置为true。 HttpResponse.SuppressFormsAuthenticationRedirect
的每个文档:
默认情况下,表单身份验证将HTTP 401状态代码转换为302 为了重定向到登录页面。这不适合 某些类型的错误,例如验证成功但是 授权失败,或当前请求是AJAX或Web时 服务请求。此属性提供了一种抑制重定向的方法 行为并将原始状态代码发送给客户端。
关于财产的价值:
如果应禁止表单身份验证重定向,则true ; 否则, false 。
为了进一步阅读,并充分赞扬Phil Haack作为我关于该主题的第一个简单信息来源,请查看他关于该主题的blog post。
答案 2 :(得分:0)
你应该看一下AuthorizeAttribute。您可以使用它或它的一些方法来装饰控制器,然后处理AngularJS中的UnAuthorized
异常(我认为状态401)。
.Net将在大多数情况下根据cookie决定是否授权请求,但这实际上取决于您使用的身份验证方案。