ruby-on-rails 如何在Ruby on Rails的单页应用中包含CSRF令牌

nnvyjq4y  于 2023-05-08  发布在  Ruby
关注(0)|答案(1)|浏览(194)

我正在用react构建一个单页应用程序前端,它可以与ruby on rails后端对话。我正在使用design和omniauth进行用户认证,我正在尝试用我的谷歌帐户登录。
我按照这里(https://developers.google.com/identity/gsi/web/guides/client-library)和这里(https://developers.google.com/identity/gsi/web/tools/configurator)的指示,我有登录与谷歌按钮运行在我的主页上。当你点击它,你选择你的谷歌帐户,它成功地POST到正确的omniauth回调地址。
问题是它抛出一个ActionController::InvalidAuthenticityToken异常,并显示消息“无法验证CSRF令牌的真实性”。我知道这是因为rails会自动将CSRF令牌注入到呈现的表单中,但在本例中,它是由外部库的javascript调用发送的。我如何发送代币?
我在我的application.html.erb文件中包含了下面的脚本标签,这是我之前发布的文档中的指示。

<script src="https://accounts.google.com/gsi/client" async defer></script>

我做了下面的react应用程序,可以用google button登录。

import React from 'react';

const SignInWithGoogle = () => {
  return (
    <div className='sign-in-with-google'>
      <div id="g_id_onload"
          data-client_id="xxxxx.apps.googleusercontent.com"
          data-context="signup"
          data-ux_mode="popup"
          data-login_uri="http://localhost:3000/users/auth/google_oauth2/callback"
          data-auto_prompt="false">
      </div>

      <div className="g_id_signin"
          data-type="standard"
          data-shape="rectangular"
          data-theme="outline"
          data-text="signin_with"
          data-size="large"
          data-logo_alignment="left">
      </div>
    </div>
  );
};

export default SignInWithGoogle;

ruby版本:3.2.2
rails版本:7.0.4.3
devise gem 4.9.2
omniauth gem 2.1.1
omniauth-google-oauth2 gem 1.1.1

kpbwa7wx

kpbwa7wx1#

默认情况下,API端点无法验证CSRF令牌。React FE是跨站点的,SSO响应也是跨站点的。
在我的混合应用中,我倾向于选择性地为所有API端点禁用CSRF:

# Disable CSRF protection on urls that start with /api/v1/
  skip_before_action :verify_authenticity_token, if: :api_endpoint?

您至少需要在OmniauthCallbacksController中禁用它。

相关问题