2016-08-29 22 views
0

我正在设计一个新网站,我正在考虑使用AJAX发布请求以获得更好的用户体验。使用AJAX POST请求来更改服务器状态是一种可接受的设计实践吗?他们在使用AJAX POST请求时是否存在任何安全问题?是否建议将服务器状态更改限制为HTTP仅限POST?Ajax POST是一种用于更改服务器状态的可接受技术?

编辑

我使用ASP.NET MVC Web框架实施。

回答

2

Post,Put,Patch和Delete(尽管最后一个很少使用)都是传统上改变服务器状态的所有请求类型。

为了回答您的问题,重要的是要考虑您正在使用的框架,因为每个框架可能有不同的最佳实践。

从技术角度来看,它们都做同样的事情,它们只有不同的语义和惯例。如果您要使用邮政的一切,我怀疑有人会抱怨

+0

谢谢回答。我排除这些信息认为它不相关,但我现在已经更新了这个问题。 – Hemant

+0

我的问题不是关于GET和POST。这是关于** HTTP ** POST与** AJAX ** POST。 – Hemant

+1

这是一样的事情,都是通过HTTP协议的请求。 Ajax只是一种技术(其中请求由脚本语言启动)而不是协议。 –

0

邮政回是传统的方式来做的事情在web应用程序的整个页面重新加载表单提交。在这种方法中,大多数代码都是在严重的一方运行。

AJAX是构建Web应用程序的一种现代方式,大多数代码都在客户端运行,以获得更好的性能和用户体验。只需要将数据发布到服务器而不是发布整个页面。 回发& Ajax都创建HTTP请求,所以说一个人比其他人不安全。在这两个请求中,攻击者都可以使用跨站点脚本(XSS)或CSRF(跨站请求伪造)来注入脚本。 AJAX呼叫本身在CORS被禁用且JSONP请求被阻止时使用“Common Origin Policy”来保护CSRF。为了防止CSRF攻击领先一步,您可以像在MVC框架中一样实施Anti Forgery令牌。可以从Web应用程序和MVC调用AJAX调用。

MVC@ html.antiforgerytoken()可以被称为在其上存储在隐藏字段和在其它的cookie关键一个密钥,并使用ValidateAntiForgeryToken滤波器形式负载,我们可以验证CSRF令牌。表单标记可能是AJAX请求的问题,因为AJAX请求可能会发送JSON数据,而不是HTML表单数据。一种解决方案是在自定义HTTP头中发送令牌。 以下是更多详细信息的示例代码片段...

示例服务器端生成反伪造令牌的代码。

/// <summary> 
/// Get Anti Forgery token 
/// </summary> 
/// <returns></returns> 
public static string GetAntiXsrfToken() 
     { 
      string cookieToken, formToken; 
      AntiForgery.GetTokens(null, out cookieToken, out formToken); 
      var responseCookie = new HttpCookie("__AntiXsrfToken") 
      { 
       HttpOnly = true, 
       Value = cookieToken 
      }; 
      if (FormsAuthentication.RequireSSL &&  HttpContext.Current.Request.IsSecureConnection) 
      { 
       responseCookie.Secure = true; 
      } 
      HttpContext.Current.Response.Cookies.Set(responseCookie); 

      return formToken; 
     } 

服务器端示例验证防伪造令牌的代码。

/// <summary> 
    /// Validate Anti Forgery token coming from secure cookie & request header 
    /// </summary> 
    static void ValidateAntiXsrfToken() 
    { 
     string tokenHeader, tokenCookie; 
     try 
     { 
// get header token      
tokenHeader = HttpContext.Current.Request.Headers.Get("__RequestVerificationToken"); 

        // get cookie token 
        var requestCookie = HttpContext.Current.Request.Cookies["__AntiXsrfToken"]; 
        tokenCookie = requestCookie.Value; 

        AntiForgery.Validate(tokenCookie, tokenHeader); 
       } 
       catch 
       { 
        HttpContext.Current.Response.Clear(); 
        HttpContext.Current.Response.StatusCode = 403; 
        HttpContext.Current.Response.End(); 
       } 
      } 

示例代码以获得防伪造令牌(一个部分),并保存到隐藏字段

<input name="__RequestVerificationToken" type="hidden" value="<%= CommonUtils.GetAntiXsrfToken() %>" /> 

示例客户端代码的一个部分从隐藏字段和另一个传递给反伪造令牌插入请求头如果请求是从同一个来源生成的,则部分将自动从客户端cookie中移除。

function CallServer(baseUrl, methodName, MethodArgument, callback) { 
    $.ajax({ 
     type: "POST", 
     url: baseUrl + methodName, 
     data: MethodArgument, 
     contentType: "application/json; charset=utf-8", 
     async: false, 
     dataType: "json", 
     headers: {'__RequestVerificationToken': $("input[name='__RequestVerificationToken']").val() 
     }, 
     success: function (data) { 
      if (callback != undefined && typeof (callback) === "function") { 
       callback(data.d); 
      } 
     }, 
     error: function (data) { 
      if (data.status == 401 || data.status == 403) 
       window.location.href = "../Common/accessdenied"; 
      else if (data.status == 419) { 
       displayUserMessage(commonMessage.RE_SESSIONINFO_NOT_FOUND, true); 
       window.location.href = "../Common/logout"; 
      } 
      else 
       displayUserMessage(commonMessage.SERVICE_NOT_RESPONDING, true); 
     } 
    }); 
} 

最后,在处理服务器端的每个AJAX请求之前调用ValidateAntiXsrfToken()函数。

您可以在这里找到更多的细节......

Which one is better? Ajax post or page post[Controller httppost] when only one form is there in a page?

http://www.asp.net/web-api/overview/security/preventing-cross-site-request-forgery-csrf-attacks

https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29_Prevention_Cheat_Sheet