programing

각도 안에 crf_token()을 보내는 방법Laravel API를 이용한 JS 양식?

muds 2023. 9. 18. 22:46
반응형

각도 안에 crf_token()을 보내는 방법Laravel API를 이용한 JS 양식?

저는 각도+라벨 휴식 어플리케이션을 만들려고 합니다.저는 제 데이터베이스의 뷰를 얻을 수 있습니다.새로운 아이템을 추가하려고 할 때.알겠습니다.500 errorcrf 토큰이 일치하지 않는다고 알려줍니다.양식 레이아웃은 다음과 같습니다.

<form class="form-horizontal" ng-submit="addItem()">

  <input type="text" ng-model="itemEntry" placeholder="Type and hit Enter to add item">
</form>

이렇게 해서 데이터베이스에 항목을 추가합니다.

$scope.addItem = function(CSRF_TOKEN) {
    $http.post('/shop', { text: $scope.itemEntry, csrf_token: CSRF_TOKEN} ).success(function(data, status) {
        if(data) {
            var last = _.last($scope.items);
            _token = CSRF_TOKEN;
            $scope.items.push({text: $scope.itemEntry, bought: false, id: (last.id + 1) });
            $scope.itemEntry = '';
            console.log($scope.items);
        } else {
            console.log('There was a problem. Status: ' + status + '; Data: ' + data);
        }
    }).error(function(data, status) {
            console.log('status: ' + status);
        });

}

애플리케이션에 사용하는 필터는 다음과 같습니다.

Route::filter('csrf', function()
{
    if (Session::token() != Input::get('_token'))
    {
        throw new Illuminate\Session\TokenMismatchException;
    }
});

블레이드 뷰에서는 이 기능을 사용하고 작동합니다.

<input type="hidden" name="_token" value="{{ csrf_token() }}" />

html 양식을 사용할 때 crf_token을 어떻게 보내나요?

감사해요.

편집 1 : 이와 같이 게시 요청에 헤더를 추가해도 오류가 발생하지 않습니다.

  $http({
    method  : 'POST',
    url     : '/shop',
    data    :  $scope.itemEntry,  // pass in data as strings
    headers : { 'Content-Type': 'application/x-www-form-urlencoded' }   
  });

CSRF 토큰을 상수로 주입하는 방법도 있습니다.헤드 태그에 다음을 추가합니다.

<script>
  angular.module("app").constant("CSRF_TOKEN", '{{ csrf_token() }}');
</script>

그러면 모듈 방식에서는 필요할 때 주입할 수 있습니다.

app.factory("FooService", function($http, CSRF_TOKEN) {
    console.log(CSRF_TOKEN);
};

아마도 당신은 이 샘플의 소스코드 Laravel + Angular를 훔쳐보고 싶을 것입니다.JS 프로젝트.

루벤스 마리우조가 인정한 해결책을 찾았지만, 나는 내가 생각하기에 더 나은 대안을 찾았다고 생각합니다.

이렇게 하면 html 스크립트에서 angularjs 앱으로 데이터를 전달할 필요가 없고 우려 사항을 더 잘 분리할 수 있습니다.예를 들어, 이것은 당신의 라라벨 앱을 단지 API로 가질 수 있게 해줍니다.

제 솔루션은 api 요청을 통해 CSRF 토큰을 얻고 이 값을 상수로 설정하는 것입니다.

또한 필요할 때 CSRF 토큰을 주입하는 대신 API http 요청 시 서버에서 확인할 수 있는 기본 헤더에 토큰을 설정합니다.

예는 larravel을 보여주지만, 어떤 심각한 프레임워크라도 유사한 것을 제공할 수 있어야 합니다.

LARAVEL의 CSRF 경로:

// Returns the csrf token for the current visitor's session.
Route::get('api/csrf', function() {
    return Session::token();
});

로 경로 보호before => 'api.csrf'필터

// Before making the declared routes available, run them through the api.csrf filter
Route::group(array('prefix' => 'api/v1', 'before' => 'api.csrf'), function() {
Route::resource('test1', 'Api\V1\Test1Controller');
Route::resource('test2', 'Api\V1\Test2Controller');
});

api.csrf거름망을 치다

// If the session token is not the same as the the request header X-Csrf-Token, then return a 400 error.
Route::filter('api.csrf', function($route, $request)
{
if (Session::token() != $request->header('X-Csrf-Token') )
{
    return Response::json('CSRF does not match', 400);
}
});

앵귤러JS는 이것을 app.js에 넣었습니다.

차단 버전:

var xhReq = new XMLHttpRequest();
xhReq.open("GET", "//" + window.location.hostname + "/api/csrf", false);
xhReq.send(null);

app.constant("CSRF_TOKEN", xhReq.responseText);

app.run(['$http', 'CSRF_TOKEN', function($http, CSRF_TOKEN) {    
    $http.defaults.headers.common['X-Csrf-Token'] = CSRF_TOKEN;
}]);

비차단 버전

var xhReq = new XMLHttpRequest();
xhReq.open("GET", "//" + window.location.hostname + "/api/csrf", true);

xhReq.onload = function(e) {
  if (xhReq.readyState === 4) {
    if (xhReq.status === 200) {
      app.constant("CSRF_TOKEN", xhReq.responseText);

      app.run(['$http', 'CSRF_TOKEN', function($http, CSRF_TOKEN) {
        $http.defaults.headers.common['X-Csrf-Token'] = CSRF_TOKEN;
      }]);
    }
  }
};

xhReq.send(null);

이제 CSRF_TOKEN 상수는 Angular의 모든 http 요청에 헤더로 주입됩니다.JS app 및 ALL API 경로는 보호됩니다.

Laravel 5를 사용하는 경우 Angular http 헤더에 CSRF 토큰을 추가할 필요가 없습니다.

각도가 있는 라라벨 5가 자동으로 해줍니다.

http://laravel.com/docs/5.1/routing#csrf-x-xsrf-token

저는 제 솔루션이 고통과 유연성이 적다고 생각합니다. 특히 카르마에 대한 앱 테스트를 생각합니다.

먼저 이 코드를 마스터 보기에 추가합니다.

 <meta name="csrf-token" content="{{ csrf_token() }}">

경로를 추가하지 않고 crf 토큰을 html 콘텐츠에 저장하였습니다.

이제 AngularJs App의 모든 요청을 CSRF 토큰으로 보호합니다.

/**
 * 
 * when it thinks testing your app unit test with Karma,
 * this solution was better than getting token via AJAX.
 * Because low-level Ajax request correctly doesn't work on Karma
 * 
 * Helper idea to me :
 * http://stackoverflow.com/questions/14734243/rails-csrf-protection-angular-js-protect-from-forgery-makes-me-to-log-out-on/15761835#15761835 
 * 
 */
var csrftoken =  (function() {
    // not need Jquery for doing that
    var metas = window.document.getElementsByTagName('meta');

    // finding one has csrf token 
    for(var i=0 ; i < metas.length ; i++) {

        if ( metas[i].name === "csrf-token") {

            return  metas[i].content;       
        }
    }  

})();

// adding constant into our app

yourAngularApp.constant('CSRF_TOKEN', csrftoken); 

Angular에 대한 기본 http 헤더를 설정해야 합니다.앵귤러의 헤더에 crf 토큰을 추가해 보겠습니다.

/*
 * App Configs
 */
blog.config(['$httpProvider', 'CSRF_TOKEN',

  function($httpProvider, CSRF_TOKEN) {


    /**
     * adds CSRF token to header
     */
    $httpProvider.defaults.headers.common['X-CSRF-TOKEN'] = CSRF_TOKEN;

 }]);

마지막으로 라라벨 쪽에서 이 변화를 위한 새로운 필터가 필요합니다.

Route::filter('csrfInHeader', function($route, $request) {

    if (Session::token() !== (string) $request->header('X-CSRF-TOKEN') ) {

        throw new Illuminate\Session\TokenMismatchException;

    }
});

"csrfInHeader" 필터는 모든 http 요청을 angular app으로 확인합니다.모든 요청에 crf 토큰을 추가할 필요는 없습니다.게다가 카르마가 당신의 앱을 테스트한다면, 당신은 테스트에 crf 토큰을 얻는 노력을 하지 않을 것입니다.

가장 쉬운 방법은 다음과 같습니다.

Route::get('/getToken','Controller@getToken');

웹 또는 api.php 파일에서

컨트롤러에서

public function getToken(){

          return csrf_token();

    }

이코드를넣습니다.

Angular 앱에서

$http.get("http://localhost:8000/getToken")
  .then(function(response) {
    alert(response.data)
  });

crf_token()을(를) 안전하게 가져오는 방법

언급URL : https://stackoverflow.com/questions/18336699/how-to-send-csrf-token-inside-angularjs-form-using-laravel-api

반응형