>

AngularJ를 사용하여 웹 페이지에서 서버로 RequestVerificationToken을 전달할 수 없습니다.

내 AngularJs 코드는 다음과 같습니다 :

var app = angular.module('validation', []);
app.controller('SignUpController', function ($scope, $http) {
    $scope.model = {};
    $scope.email = {};
    $scope.sendEmail = function () {
        $http({
            method: 'POST',
            url: '/Contact/Test',
            data: $scope.email,
            headers: {
                'RequestVerificationToken': $scope.antiForgeryToken
            }
        }).success();
    };
});

맞춤 속성 코드 :

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
    public class CustomAntiForgeryTokenAttribute : FilterAttribute, IAuthorizationFilter
    {

        private void ValidateRequestHeader(HttpRequestBase request)
        {
            string cookieToken = String.Empty;
            string formToken = String.Empty;
            string tokenValue = request.Headers["RequestVerificationToken"];
            if (!String.IsNullOrEmpty(tokenValue))
            {
                string[] tokens = tokenValue.Split(':');
                if (tokens.Length == 2)
                {
                    cookieToken = tokens[0].Trim();
                    formToken = tokens[1].Trim();
                }
            }
            AntiForgery.Validate(cookieToken, formToken);
        }
        public void OnAuthorization(AuthorizationContext filterContext)
        {
            try
            {
                if (filterContext.HttpContext.Request.IsAjaxRequest())
                {
                    ValidateRequestHeader(filterContext.HttpContext.Request);
                }
                else
                {
                    AntiForgery.Validate();
                }
            }
            catch (HttpAntiForgeryException e)
            {
                throw new HttpAntiForgeryException("Anti forgery token cookie not found");
            }
        }
    }

양식은 :

@functions{
    public string GetAntiForgeryToken()
    {
        string cookieToken, formToken;
        AntiForgery.GetTokens(null, out cookieToken, out formToken);
        return cookieToken + ":" + formToken;
    }
}
<div ng-app="validation" ng-controller="SignUpController">
    <form role="form" id="frmContact" action="@Url.Action("Index", "Contact")" method="POST">
        <input id="antiForgeryToken" ng-model="antiForgeryToken" type="hidden" ng-init="antiForgeryToken='@GetAntiForgeryToken()'" />
        <fieldset class="form-group">
            @Html.LabelFor(x => x.EmailTitle)
            @Html.TextBoxFor(x => x.EmailTitle, new { placeholder = @Resource.EmailTitle, @class = "form-control", data_ng_model = "new.email.title" })
        </fieldset>
        <fieldset class="form-group">
            @Html.LabelFor(x => x.EmailAddress)
            @Html.TextBoxFor(x => x.EmailAddress, new { placeholder = @Resource.EmailAddress, @class = "form-control", data_ng_model = "new.email.address" })
        </fieldset>
        <fieldset class="form-group">
            @Html.LabelFor(x => x.EmailMessage)
            @Html.TextAreaFor(x => x.EmailMessage, new { placeholder = @Resource.EmailMessage, @class = "form-control", data_ng_model = "new.email.message" })
        </fieldset>

        <div>
            <button type="submit" name="btnEmailForm" id="btnEmailForm" class="btnLogin" ng-click="sendEmail()" value="sendMessage">@Resource.ContactFormSendMessageButton</button>
        </div>
        <div id="errorMessages" class="error">{{message}}</div>
    </form>
</div>

다음 게시물을 읽었지만 문제를 해결할 수 없으며 https://github.com/techbrij/angularjs-asp-net-mvc 는이 예에서는 작동하지만 MVC 응용 프로그램에서는 작동하지 않습니다.

http://techbrij.com/angularjs-antiforgerytoken-asp-net-mvc

https : // parthivpandya.wordpress.com/2013/11/25/angularjs-and-antiforgerytoken-in-asp-net-mvc/

AngularJS 웹 API AntiForgeryToken CSRF

http : //bartwullems.blogspot .co.uk/2014/10/angularjs-and-aspnet-mvc-isajaxrequest.html

반대 조명 토큰을 정확히 어디에 넣는 곳

http://www.ojdevelops.com /2016/01/using-antiforgerytokens-in-aspnet-mvc.html

누구나이 문제를 도와 줄 수 있습니까?

  • 답변 # 1

    이 경우 양식 submit 를 수행합니다.  그리고 $scope.sendEmail  이 동작을 방지하기 위해 ng-submit 를 사용할 수 있습니다.  지령. 또한 속성을 추가하십시오 : name= '__RequestVerificationToken'  그리고 ng-value="antiForgeryToken"  해당 input 에 .

  • 답변 # 2

    중요 : [ValidateAntiForgeryToken] 의 기본 동작   __RequestVerificationToken 를 기대  양식 값의 토큰. 양식 값 형식으로 서버에 요청을 보내려면 content-type 가 필요합니다.   application/x-www-form-urlencoded 로 설정 . 그러나 불행히도이 옵션이 없었으며 콘텐츠 유형은 application/json 였습니다. . 따라서이 맞춤 경로를 사용했습니다.

    내가 취한 접근 방식을 설명하겠습니다

    1 단계 : @Html.AntiForgeryToken() 선언  아래 표시된대로보기 (.cshtml)에서 :

    <form id="inputForm" name="inputForm" ng-submit="submit(broker)" novalidate>
            @Html.AntiForgeryToken()
            /* other controls of form */
    </form>
    
    

    2 단계 : @Html.AntiForgeryToken()  숨겨진 필드를 렌더링하여 토큰 값을 다음과 같이 보유합니다 :

    <input name="__RequestVerificationToken" type="hidden" value="GvTcz2tTgHOS2KK_7jpHvPWEJPcbJmHIpSAlxY1">
    
    

    3 단계 : 위조 방지 토큰 확인을위한 사용자 정의 속성 생성

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]    
    public class HbValidateAntiForgeryToken : FilterAttribute, IAuthorizationFilter, IExceptionFilter    
    {    
        public void OnAuthorization(AuthorizationContext filterContext)
        {
            try
            {
                var antiForgeryCookie = filterContext.HttpContext.Request.Cookies[AntiForgeryConfig.CookieName];
                AntiForgery.Validate(antiForgeryCookie != null ? antiForgeryCookie.Value : null,
                    filterContext.HttpContext.Request.Headers["__RequestVerificationToken"]);                
            }
            catch (Exception ex)
            {                
                throw new SecurityException("Unauthorised access detected and blocked");
            }
        }
        public void OnException(ExceptionContext filterContext)
        {
            if (filterContext.Exception != null &&
                filterContext.Exception is System.Security.SecurityException)
            {
                filterContext.Result = new HttpUnauthorizedResult();
                // Handle error page scenario here
            }
        }
    }
    
    

    4 단계 : 필요한 경우 위의 속성을 선언합니다 (컨트롤러의 HttpPost 메소드에서만. HttpGet에서 선언하지 마십시오)

    [HttpPost]
    [HbValidateAntiForgeryToken]
    public JsonResult IsUsernameExists(string username)
    {
    }
    
    

    5 단계 : AngularJS에서 팩토리 패스 __RequestVerificationToken  헤더로.

    hbServices.factory('RegistrationService', ['$resource',
    function ($resource) {
        return $resource(applicationPath + 'api/MyUserMembership/:dest', {}, {
            createNewUser: { method: 'POST', isArray: false, params: { dest: 'CreateNewUser' }, 
                             headers: { 
                                 '__RequestVerificationToken': $('input[name="__RequestVerificationToken"]').val()
                                }
                            },
            isUsernameExists: { method: 'POST', isArray: false, params: { dest: 'IsUsernameExists' }, 
            headers: { 
                '__RequestVerificationToken': $('input[name="__RequestVerificationToken"]').val()
               }
           }
        });
    }]);
    
    

    __RequestVerificationToken 의 가치를 전달하는 방식에 유의하십시오  ASP.NET MVC의 @Html.AntiForgeryToken() 에 의해 렌더링 된 숨겨진 필드에서 읽습니다. .

    응용 프로그램에서 jquery를 사용하고 있으며 jquery에 대한 참조가 이미 있으므로 값을 쉽게 읽을 수 있습니다. 다른 방법으로이 값을 읽을 수 있습니다

    요약 와이즈 비즈  위조 토큰의 가치를 검증하는 마술은 여기까지 훌륭합니다. 이것이 도움이 되길 바랍니다!

    AntiForgery.Validate()

관련 자료

  • 이전 python - 동일한 문자열 목록을 사용하여 목록 목록 인덱싱
  • 다음 python : matplotlib의 가로 막대 그래프 주석 [중복]