我在导航到 URL 时遇到问题。我的默认页面设置为登录,我的应用程序 URL 是 http://localhost:12345/#/
。
这很好用,但用户可以通过两种方式登录到应用程序
- 直接通过应用程序。
- 通过查询字符串获取用户名和密码。
当应用程序通过查询字符串进行日志记录时,URL 类似于 http://localhost:12345?auth=123654654656564/#/
。
我想从 URL 中删除身份验证值。我试图映射路由,但它不起作用。
routes.MapRoute(
name: "Default",
url: "{controller}/{action}",
defaults: new { controller = "Account", action = "Login"}
);
而且我还尝试再创建一个操作结果,该结果将返回view
routes.MapRoute(
name: "ActualDefault",
url: "{controller}/{action}",
defaults: new { controller = "Account", action = "LoginQuery" }
);
控制器:
public ActionResult Login()
{
if (Request.QueryString.Count > 0 && Request.QueryString != null)
{
//validating
return RedirectToAction("LoginQuery", "Account");
}
else
{
return View();
}
}
public ActionResult LoginQuery()
{
return View("Index");
}
上面的代码删除了查询字符串,但 URL 将被http://localhost:12345/Account/LoginQuery/#/
。
我只需要像http://localhost:12345/#/
这样的 URL.
通过查询字符串登录
如果不指出这是一种极其糟糕的做法,那将是疏忽大意。登录应用程序时,应始终使用 HTTP POST,并在帖子正文(而不是查询字符串)中发送用户机密。
看
- 处理表单编辑和发布方案
- 在 MVC 中提交带有参数 ASP.NET 表单
- 使用剃须刀构建 ASP.NET MVC 表单
请注意,您也可以在纯 HTML(或通过 angularjs)中创建表单来调用 MVC 操作方法,或者您可以通过 JavaScript 或其他编程语言制作 HTTP POST 来执行相同的操作。
MVC 路由完全忽略查询字符串值。但是,您可以使自定义路由使用查询字符串值。
public class LoginViaQueryStringRoute : RouteBase
{
public override RouteData GetRouteData(HttpContextBase httpContext)
{
var path = httpContext.Request.Path;
if (!string.IsNullOrEmpty(path))
{
// Don't handle URLs that have a path /controller/action
return null;
}
var queryString = httpContext.Request.QueryString;
if (!queryString.HasKeys())
{
// Don't handle the route if there is no query string.
return null;
}
if (!queryString.AllKeys.Contains("username") && !queryString.AllKeys.Contains("password"))
{
// Don't handle the case where controller and action are missing.
return null;
}
var routeData = new RouteData(this, new MvcRouteHandler());
routeData.Values["controller"] = "Account";
routeData.Values["action"] = "LoginQuery";
routeData.Values["username"] = queryString["username"];
routeData.Values["password"] = queryString["password"];
return routeData;
}
public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{
return null;
}
}
用法
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.Add(new LoginViaQueryStringRoute());
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
此路由现在将匹配http://localhost:12345/?username=foo&password=bar
并将其发送到LoginQuery
操作方法。
通过http://localhost:12345/#/
登录
目前还不清楚您期望它如何工作。由于哈希标签之后的所有内容通常都不会从浏览器发送到服务器,因此http://localhost:12345/#/
等同于http://localhost:12345/
。因此,您实际上是在说"我希望我的主页成为登录页面"。
在典型的 MVC 应用程序中,您将在主页上设置一个AuthorizeAttribute
,以将用户重定向到登录页面。用户登录后,他们将被重定向回主页(或通常是他们最初请求的任何安全页面)。
[Authorize]
public ActionResult Index()
{
return View();
}
如果希望所有应用程序都受到保护,则可以全局注册AuthorizeAttribute
,并在公共操作方法(例如登录和注册页面)上使用AllowAnonymousAttribute
。
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new AuthorizeAttribute());
filters.Add(new HandleErrorAttribute());
}
}
以及您的登录操作方法:
[AllowAnonymous]
public ActionResult Login()
{
//...
}
[AllowAnonymous]
[HttpPost]
public ActionResult Login(LoginModel model)
{
//...
}
[AllowAnonymous]
public ActionResult LoginQuery(string username, string password)
{
//...
}
但是,这是一个典型的仅限 MVC 的应用程序。
如果您正在使用Angular来制作SPA,那么这可能是一个非常不同的故事。也就是说,您可能会在不执行HTTP 302重定向到登录表单的情况下在客户端切换视图(也许它会是一个弹出窗口 - 谁知道呢)。关键是,如果没有关于客户端如何设置以与 MVC 通信的任何详细信息,除了通常如何设置 MVC 以在多页应用程序中工作之外,不可能为您提供有关为客户端设置 MVC 的任何有用建议。
注意:我可以告诉您,您的路由配置错误。
Default
和ActualDefault
定义不能存在于相同的路由配置中,因为第一场比赛总是获胜,因此第一场比赛将运行,而另一场比赛永远不会运行。这两个路由 URL 定义都将匹配长度为 0、1 或 2 段的任何 URL,因此路由表中第一个的 URL 将匹配,另一个将是无法访问的执行路径。