1

我创建了 2 个非常简单的方法:

[Authorize]
[HttpGet]
public string getUser()
{
   return User.Identity.Name;
}

[HttpPost]
public bool SignIn(Credentials cred)
{
   var user = userRepository.ValidateUser(cred);
   if (user != null)
   {
      if (user.IsActive)
      {
         FormsAuthentication.SetAuthCookie(userRepository.GetUserIdByEmail(cred.Email).ToString(), cred.RememberMe);
         FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1,
         user.UserId.ToString(),
         DateTime.UtcNow,
                  DateTime.UtcNow.AddDays(Convert.ToInt32(ConfigurationManager.AppSettings["CookieTimeoutInDays"])),
         true,
         "MyTicket",
         FormsAuthentication.FormsCookiePath);

         //Encrypt the ticket.
         string encTicket = FormsAuthentication.Encrypt(ticket);

         //Create the cookie.
         HttpCookie mycookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);

         // Set the cookie's expiration time to the tickets expiration time
         if (ticket.IsPersistent)
            mycookie.Expires = ticket.Expiration;

         Response.AddHeader(FormsAuthentication.FormsCookieName, encTicket);
         return true;
       }
       else
       return false;
     }
     else
     {
        return false;
     }
  }

我将这些函数放在一个 API 控制器和一个普通控制器中(唯一不同的是HttpContext.Current.Response.AddHeader(FormsAuthentication.FormsCookieName, encTicket);它在 api 控制器中时)。当我使用普通控制器进行身份验证并将相同的 cookie 传回以调用getUser()它时,它可以工作,但是当我对 API 控制器执行此操作时,它不起作用..我使用移动设备来调用这两个控制器,而不是浏览器。现在我了解 API 控制器通常通过在每次调用的标头中传递用户名和密码来使用基本身份验证,但是从普通控制器执行此操作有什么问题吗?与普通控制器相比,使用 asp.net Web API 有什么优势?

4

1 回答 1

0

当我使用普通控制器进行身份验证并将相同的 cookie 传回调用 getUser() 时,它可以工作,但是当我对 API 控制器执行此操作时,它不起作用

我不确定为什么会这样。如果您使用的是普通模板,请注意您的 ApiController 将位于 /api 路由下,并注意操作名称不会成为 URL 的一部分。如果您的 WebApiConfig 说:

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

并且您的控制器类名为 FooController,那么您的 ApiController URL 将类似于:http://:33504/api/Foo

(对于 GET 和 POST)。

将 cookie 与 Web API 一起使用通常不是最好的方法,但如果您有特殊需要,它是可能的。

还有几个地方你可能会被绊倒:

  1. 您正在生成表单身份验证 cookie 两次。SetAuthCookie 行执行一次,并将其放入 cookie 标头中。然后, Response.AddHeader 再次执行此操作,将其放入自定义标头(不是 cookie 标头)中。

  2. 当您说 Response.AddHeader(FormsCookieName) 时,我认为您的意思是:Response.SetCookie(myCookie)。您当前的代码正在添加一个名为 FormsCookieName 的自定义标头;它没有添加具有该 cookie 名称的 cookie(在 Set-Cookie 标头中)。

  3. 对于 Web API,通常不建议使用 HttpContext.Current.Response。相反,请考虑返回 HttpResponseMessage 并设置该对象的标头属性。

现在我了解 API 控制器通常通过在每次调用的标头中传递用户名和密码来使用基本身份验证,但是从普通控制器执行此操作有什么问题吗?

当您使用 Web API 时,您通常会使用 REST,而 cookie 不太适合那里的超媒体理念。如果你不做超媒体/REST,那么我想你可以使用 cookie,尽管它通常不是最合适的。

与普通控制器相比,使用 asp.net Web API 有什么优势?

Web API 为您提供了一个自托管的故事、进行内容协商的能力和一个很好的 HTTP 编程模型。MVC 更多地是专门围绕 HTML 设计的(而不是其他内容类型)。如果您要返回 HTML,MVC 可能是有意义的。如果您的应用程序中没有任何内容返回 HTML,那么 Web API 可能更适合。

不过,对于这个控制器,我会在你的应用程序的其余部分做任何你做的事情。(我不会为这个控制器选择不同的框架。)

于 2013-04-10T22:49:58.150 回答