Rails CSRF Protection + Angular.js: protect_from_forging으로 POST에서 로그아웃할 수 있습니다.
이 경우,protect_from_forgery
옵션은 application_controller에 기재되어 있기 때문에 로그인하여 임의의 GET 요청을 실행할 수 있지만 Rails는 첫 번째 POST 요청 시 세션을 리셋하고 로그아웃합니다.
돌렸습니다.protect_from_forgery
옵션은 일시적으로 꺼지지만 Angular.js와 함께 사용합니다.무슨 방법이 있을까요?
DOM에서 CSRF 값을 읽는 것은 좋은 해결책이 아니라 회피책이라고 생각합니다.
여기 각진 형태의 문서가 있습니다.JS 공식 웹사이트 http://docs.angularjs.org/api/ng.$http :
도메인에서 실행되는 JavaScript만 쿠키를 읽을 수 있으므로 XHR이 도메인에서 실행되는 JavaScript에서 가져온 것임을 서버에서 확인할 수 있습니다.
이 기능(CSRF Protection)을 이용하려면 서버는 첫 번째 HTTP GET 요구 시 XSRF-TOKEN이라는 JavaScript 판독 가능한 세션쿠키에 토큰을 설정해야 합니다.이후 비GET 요구에서는 서버는 쿠키가 X-XSRF-TOKEN HTTP 헤더와 일치하는지 확인할 수 있습니다.
이러한 순서에 근거한 솔루션을 다음에 나타냅니다.
먼저 cookie를 설정합니다.
# app/controllers/application_controller.rb
# Turn on request forgery protection
protect_from_forgery
after_action :set_csrf_cookie
def set_csrf_cookie
cookies['XSRF-TOKEN'] = form_authenticity_token if protect_against_forgery?
end
다음으로 GET 이외의 요구마다 토큰을 확인해야 합니다.
Rails는 이미 유사한 방법으로 구축되었기 때문에 단순히 논리를 추가하기 위해 덮어쓸 수 있습니다.
# app/controllers/application_controller.rb
protected
# In Rails 4.2 and above
def verified_request?
super || valid_authenticity_token?(session, request.headers['X-XSRF-TOKEN'])
end
# In Rails 4.1 and below
def verified_request?
super || form_authenticity_token == request.headers['X-XSRF-TOKEN']
end
기본 레일 CSRF 보호를 사용하는 경우(<%= csrf_meta_tags %>
)는 다음과 같이 Angular 모듈을 설정할 수 있습니다.
myAngularApp.config ["$httpProvider", ($httpProvider) ->
$httpProvider.defaults.headers.common['X-CSRF-Token'] = $('meta[name=csrf-token]').attr('content')
]
또는 CoffeeScript를 사용하지 않는 경우(뭐라고요?)):
myAngularApp.config([
"$httpProvider", function($httpProvider) {
$httpProvider.defaults.headers.common['X-CSRF-Token'] = $('meta[name=csrf-token]').attr('content');
}
]);
필요에 따라서, 다음과 같은 비 GET 요구에 대해서만 헤더를 송신할 수 있습니다.
myAngularApp.config ["$httpProvider", ($httpProvider) ->
csrfToken = $('meta[name=csrf-token]').attr('content')
$httpProvider.defaults.headers.post['X-CSRF-Token'] = csrfToken
$httpProvider.defaults.headers.put['X-CSRF-Token'] = csrfToken
$httpProvider.defaults.headers.patch['X-CSRF-Token'] = csrfToken
$httpProvider.defaults.headers.delete['X-CSRF-Token'] = csrfToken
]
또, HungYuHei의 회답도 확인해 주세요.이 답변은 클라이언트가 아닌 서버상의 모든 베이스를 망라하고 있습니다.
angular_rails_csrf gem은 HungYuHei의 답변에서 설명된 패턴에 대한 지원을 모든 컨트롤러에 자동으로 추가합니다.
# Gemfile
gem 'angular_rails_csrf'
모든 이전 답변을 병합하고 사용 중인 답변에 의존합니다.Devise
인증 보석
먼저 보석을 추가합니다.
gem 'angular_rails_csrf'
다음으로, 추가rescue_from
application_controller.block:
protect_from_forgery with: :exception
rescue_from ActionController::InvalidAuthenticityToken do |exception|
cookies['XSRF-TOKEN'] = form_authenticity_token if protect_against_forgery?
render text: 'Invalid authenticity token', status: :unprocessable_entity
end
그리고 마지막으로 각진 앱에 인터셉터 모듈을 추가합니다.
# coffee script
app.factory 'csrfInterceptor', ['$q', '$injector', ($q, $injector) ->
responseError: (rejection) ->
if rejection.status == 422 && rejection.data == 'Invalid authenticity token'
deferred = $q.defer()
successCallback = (resp) ->
deferred.resolve(resp)
errorCallback = (resp) ->
deferred.reject(resp)
$http = $http || $injector.get('$http')
$http(rejection.config).then(successCallback, errorCallback)
return deferred.promise
$q.reject(rejection)
]
app.config ($httpProvider) ->
$httpProvider.interceptors.unshift('csrfInterceptor')
나는 다른 대답들을 보고 그들이 훌륭하고 잘 생각해냈다고 생각했다.레일즈 앱은 좀 더 심플한 솔루션이라고 생각했기 때문에 공유하려고 했습니다.제 레일 앱은 기본 설정으로 제공되었습니다.
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
end
댓글을 읽었는데, 각도에서 CSRF 에러를 피하고 싶은 것 같았습니다.이걸로 바꿨는데
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :null_session
end
그리고 이제 작동한다!이것이 효과가 없을 이유는 없지만, 다른 포스터에서 몇 가지 통찰력을 얻고 싶습니다.
Hung Yu Hei의 답변 내용을 응용 프로그램에 사용했습니다.다만, 인증에 Gand를 사용한 경우와 애플리케이션에 디폴트를 사용한 경우의 문제 등, 몇개의 추가의 문제가 있는 것을 알았습니다.
protect_from_forgery with: :exception
관련된 스택 오버플로우 질문과 답변에 주목하여 다양한 고려사항을 정리한 보다 장황한 블로그 투고를 작성했습니다.이 솔루션과 관련된 부분은 애플리케이션 컨트롤러에 있습니다.
protect_from_forgery with: :exception
after_filter :set_csrf_cookie_for_ng
def set_csrf_cookie_for_ng
cookies['XSRF-TOKEN'] = form_authenticity_token if protect_against_forgery?
end
rescue_from ActionController::InvalidAuthenticityToken do |exception|
cookies['XSRF-TOKEN'] = form_authenticity_token if protect_against_forgery?
render :error => 'Invalid authenticity token', {:status => :unprocessable_entity}
end
protected
def verified_request?
super || form_authenticity_token == request.headers['X-XSRF-TOKEN']
end
나는 이것에 대한 매우 빠른 해답을 찾았다.제가 해야 할 일은 다음과 같습니다.
엔 a.를 합니다.$scope
예를 들어 토큰을 포함하는 변수(예: 형식 앞) 또는 컨트롤러 초기화가 더 우수합니다.
<div ng-controller="MyCtrl" ng-init="authenticity_token = '<%= form_authenticity_token %>'">
b. 나의 앵귤러에서JS 컨트롤러, 새 엔트리를 저장하기 전에 해시에 토큰을 추가합니다.
$scope.addEntry = ->
$scope.newEntry.authenticity_token = $scope.authenticity_token
entry = Entry.save($scope.newEntry)
$scope.entries.push(entry)
$scope.newEntry = {}
더 이상 할 일이 없다.
angular
.module('corsInterceptor', ['ngCookies'])
.factory(
'corsInterceptor',
function ($cookies) {
return {
request: function(config) {
config.headers["X-XSRF-TOKEN"] = $cookies.get('XSRF-TOKEN');
return config;
}
};
}
);
angularjs쪽에서 작동한다!
언급URL : https://stackoverflow.com/questions/14734243/rails-csrf-protection-angular-js-protect-from-forgery-makes-me-to-log-out-on
'programing' 카테고리의 다른 글
Woocommerce - 주문 품목의 가격과 수량을 가져옵니다. (0) | 2023.04.01 |
---|---|
스키마 'SA'가 존재하지 않으며 테이블을 삭제합니다. (0) | 2023.04.01 |
T-SQL: SELECT를 사용하여 테이블을 작성하려면 어떻게 해야 합니까? (0) | 2023.04.01 |
SAP UI5와 다른 Javascript 프레임워크 비교 (0) | 2023.03.22 |
React 경로용 Apache 서버 설정 방법 (0) | 2023.03.22 |