복붙노트

[RUBY-ON-RAILS] 단일 페이지 응용 프로그램 및 CSRF 토큰

RUBY-ON-RAILS

단일 페이지 응용 프로그램 및 CSRF 토큰

나는 레일 CSRF 보호 메커니즘을 단일 페이지 응용 프로그램 (엠버, 각도, 나는 걱정하지 않는다 반응)를 사용합니다.

나는이 같은와 ApplicationController에 때마다 토큰을 만들 필요가 있는지 궁금 해요 :

class ApplicationController < ActionController::Base

  after_action :set_csrf_cookie

  def set_csrf_cookie
    cookies["X-CSRF-Token"] = form_authenticity_token
  end

end

또는 그냥 토큰 번을 만들 수 있습니다.

세션 당 또는 (비 GET) 요청에 따라?

나는 세션이 유효 오른쪽 때까지 토큰이 여전히 유효하다고 생각?

밝히다:

토큰 CSRF 때마다 내가 페이지를 탐색 나는 레일을 기본 응용 프로그램 (서버 렌더링 된 페이지) 업데이트를 참조하십시오. 이 변화 할 때마다 그래서.

그래서 내 상황에서 나는 이전 CSRF 토큰 아직도 그 세션에 대한 좋은 각 after_action에 대한 새로운 토큰을 생성합니다. 그럼, 어떻게 이전 토큰을 무효화? 내가해야?

나는 그것이 바로 의미가 무효 경우에만 때문에?

해결법

  1. ==============================

    1.당신은 세션 당 한 번만 토큰 CSRF를 잡아해야합니다. 당신은 브라우저에서 붙잡고 모든 (비 GET) 요청을 보낼 수 있습니다.

    당신은 세션 당 한 번만 토큰 CSRF를 잡아해야합니다. 당신은 브라우저에서 붙잡고 모든 (비 GET) 요청을 보낼 수 있습니다.

    레일은 모든 요청에 ​​토큰 새로운 CSRF를 생성하기 위해 나타납니다,하지만 하나라도 해당 세션에서 생성 된 토큰 받아 들일 것입니다. 실제로, 그것은 단지 SSL 침해 공격으로부터 보호하기 위해, 요청에 따라 한 번 패드를 사용하여 하나의 토큰을 마스킹된다. https://stackoverflow.com/a/49783739/2016618에서 자세한 내용. 이러한 토큰을 / 추적 저장할 필요가 없습니다.

    난 강력 레일의 protect_from_forgery 지시어를 사용하는 대신 헤더 자신의 토큰 CSRF를 암호화하는 것이 좋습니다. 그것은 다른 요청에 따라 토큰 마스크 생성합니다.

    당신은 확실히 그 많은 코드와이 직접 재현 할 수 있지만, 당신이 필요 했어 왜 표시되지 않습니다.

    예! 당신이 쿠키로 인증하는 경우, CSRF 보호가 필요합니다. 쿠키는 모든 요청과 함께 전송되기 때문에 악의적 인 웹 사이트가 사이트에 POST 요청을 보내고는 로그인 한 사용자를 대신하여 요청을 수행 할 수 있도록이이다. CSRF 토큰 방지이, 악성 사이트가 토큰 CSRF를 알 수 없습니다 때문입니다.

  2. ==============================

    2.당신이 SPA 응용 프로그램과 함께 갈 경우에 당신은 대부분 레일즈는 단지 API로 사용합니다. CSRF 토큰은 SPA ... 서버 렌더링하지 않도록 설계되었다. SPA에서는 이미 CSRF 또 다른 토큰을 사용할 필요가 없습니다 있도록 인증하는 동안 토큰을 사용합니다. CSRF는 사이트 간 통화에 대한 보호로 설계했지만, API 자체는이 인증, 때까지 어디에서 요청을 허용하는 방식으로 설계.

    당신이 SPA 응용 프로그램과 함께 갈 경우에 당신은 대부분 레일즈는 단지 API로 사용합니다. CSRF 토큰은 SPA ... 서버 렌더링하지 않도록 설계되었다. SPA에서는 이미 CSRF 또 다른 토큰을 사용할 필요가 없습니다 있도록 인증하는 동안 토큰을 사용합니다. CSRF는 사이트 간 통화에 대한 보호로 설계했지만, API 자체는이 인증, 때까지 어디에서 요청을 허용하는 방식으로 설계.

    그냥 API에 대한 사용하지 않도록 설정하고 그게 다야. 나는 모든 API 컨트롤러의 상속됩니다 일부 API 네임 스페이스 및 설정 BaseController, 함께 갈 것입니다. 당신은 protect_from_forgery가 설정해야합니다 :

    class API::BaseController < ApplicationController
      protect_from_forgery with: :null_session
    end
    
  3. ==============================

    3.나는 당신이 직면하고있는 어떤 정확한 문제 모른다. 당신이 새로운 레일 버전 및 필요 CSRF 문제를 점점하지만 레일 CSRF 토큰을 포함합니다 아약스 요청에 아래의 단계를 수행 할 수 있습니다.

    나는 당신이 직면하고있는 어떤 정확한 문제 모른다. 당신이 새로운 레일 버전 및 필요 CSRF 문제를 점점하지만 레일 CSRF 토큰을 포함합니다 아약스 요청에 아래의 단계를 수행 할 수 있습니다.

    최근에 나는 레일 5.1 응용 프로그램을 사용했습니다.

    API를 I에서 일부 데이터를 가져 오기 위해 아약스 호출을 사용하는 경우 CSRF 토큰 문제를 얻고 있었다 :

    ‘WARNING: Can't verify CSRF token authenticity rails’
    

    그 이유는 있었다

    5.1 제거 JQuery와에 대한 지원이 기본적으로 jquery_ujs 및 추가 레일

    //= require rails-ujs in application.js
    

    그것은 다음과 같은 일을한다 :

    그러나 기본적으로 아약스 요청에 대한 토큰 CSRF 포함되지 않습니다. 그 조심하십시오. 우리는 명시 적으로처럼 통과해야 :

    $( document ).ready(function() {
      $.ajaxSetup({
        headers: {
          'X-CSRF-Token': Rails.csrfToken()
        }
      });
      ----
      ----
    });
    

    레일 5.1 버전에서, 당신은 JS에서 '레일'클래스를 얻고, 기능을 활용할 수 있습니다.

    최신 정보: 당신이 레일 서버 측 및 다른 프론트 엔드를 사용하는 경우, 당신은 정말 레일 CSRF 토큰을 제공하는 사용하지 않습니다. 그것 때문에 정말 당신이 사용하고있는 백엔드 서비스는 중요하지.

    당신의 목표는 CSRF를 차단하는 경우, 당신은 당신의 레일 백엔드 즉, 백엔드에서 CORS를 설정해야합니다. 레일 이제이에 대한 초기화에 별도의 파일을 제공하고있다. 당신은 당신의 백엔드에 아약스 요청을 보낼 수있는 사이트 말할 수 있습니다.

    여기에 편집 :

    config/initializers/cors.rb
    

    당신이 인증을 원하는 경우, 기본 인증, 토큰 인증 또는 JWT를 사용

  4. ==============================

    4.난 그냥 질문에 대답합니다. 자세한 내용은이 문서에 설명되어 있습니다 :  https://blog.eq8.eu/article/rails-api-authentication-with-spa-csrf-tokens.html

    난 그냥 질문에 대답합니다. 자세한 내용은이 문서에 설명되어 있습니다 :  https://blog.eq8.eu/article/rails-api-authentication-with-spa-csrf-tokens.html

    CSRF 토큰 세션의 수명 기간 동안 유효합니다. 따라서 예 그냥 로그인 후 세션 기간 동안 토큰 하나 CSRF를 생성하는 데 괜찮습니다.

    class LoginController < ApplicationController
      def create
        if user_password_match
          # ....
          cookie[:my_csrf_token]= form_authenticity_token
        end
      end
    end
    

    당신이 제안하는 또는 당신은 쿠키 같은 방법으로 새로 고칠 수 있습니다

    class ApplicationController < ActionController::Base
    
      after_action :set_csrf_cookie
    
      def set_csrf_cookie
        cookies["my_csrf_token"] = form_authenticity_token
      end
    
    end
    

    귀하의 SPA는 쿠키를 읽고 헤더로 설정해야합니다.

    둘 다 똑같이 유효

    또는 당신은 로그인 응답으로 토큰 CSRF를 제공 할 수 SPA는 어딘가에 저장하고 X-CSRF 토큰 헤더를 사용합니다 :

    curl POST  https://api.my-app.com/login.json  -d "{"email":'equivalent@eq8.eu", "password":"Hello"}"  -H 'ContentType: application/json'
    # Cookie with session_id was set
    
    # response:
    
    {  "login": "ok", "csrf": 'yyyyyyyyy" }
    
    # next request 
    
     curl POST  https://api.my-app.com/transfer_my_money  -d "{"to_user_id:":"1234"}"  -H "ContentType: application/json" -H "X-CSRF-Token: yyyyyyyyy"
    

    당신이 SESSION_ID을 보낼 쿠키를 사용하지 않는 경우, 그러므로 당신의 API 인증을 위해 단지 인증 헤더를 사용하고 있습니다. 그럼 당신은 CSRF 보호를 필요로하지 않습니다.

    예:

    curl POST  https://api.my-app.com/login.json  -d "{"email":'equivalent@eq8.eu", "password":"Hello"}"  -H 'ContentType: application/json'
    # No cookie/session is set
    
    # response:
    { "login": "ok", "jwt": "xxxxxxxxxxx.xxxxxxxx.xxxxx" }
    
    # Next Request:
    curl POST  https://api.my-app.com/transfer_my_money  -d "{"to_user_id:":"1234"}"  -H "ContentType: application/json" -H "Authentication: Bearer xxxxxxxxxxx.xxxxxxxx.xxxxx"
    

    다시 한 번, 이것은 당신이 사용자 식별을 위해 쿠키를 사용하지 않는 경우에만입니다! CSRF이 경우에는 문제가되지 않습니다하지만 여전히 크로스 사이트 스크립팅 공격으로부터 보호 그래서, 당신의 통신 등 (HTTPS) 만 있는지 확인 ...

  5. from https://stackoverflow.com/questions/50159847/single-page-application-and-csrf-token by cc-by-sa and MIT license