新手问题 微信小程序向 Rails 应用发送 POST 请求时报错 InvalidAuthenticityToken

baboon · June 26, 2019 · Last by jasl replied at July 01, 2019 · 1797 hits

代码如下:

sessions_controller.rb

class SessionsController < ApplicationController
  def new
  end

  def create
    @user = User.find_by(username: params[:sessions][:username])
    if @user && @user.authenticate(params[:sessions][:password])
      login(@user)  
      respond_to do |format|
        format.html { redirect_to @user, notice: "Logged in!" }
        format.json { render 'users/show', status: :ok, location: @user }
      end
    else
      respond_to do |format|
        format.html { redirect_to login_path, notice: "invalid username/password combination" }
        format.json { render json: @user.errors, status: :invalid_username_password_combination }
      end
    end
  end
end

小程序的 index.js

var url = "http://localhost:3000/login"
wx.request({
      url: url,
      success(res){
        var authenticity_token
        authenticity_token = res.data.split("\n")[5].split(" ")[2].replace(/content=/g, "").replace(/\"/g, ""),
        wx.request({
          url: url + ".json",
          method: "POST",
          dataType: "json",
          data: {
            authenticity_token: authenticity_token,
            sessions: {'username': 'xsrong', 'password': '12345678'},
            commit: "Login"
          },
          success(res) {
            console.log(res.statusCode)
            console.log(res.data)
          }
        })
      }
    })

思路大概就是小程序先发送一次 get 请求,然后从返回来的 data 中拿到 authenticity_token,然后再用这个 token 去发送 post 请求。 get 请求可以正常进行,但是 post 请求就一直出错。报错如下:

另外,除了报 InvalidAuthenticityToken,还会报一个 HTTP Origin header (http://127.0.0.1:13160) didn't match request.base_url (http://localhost:3000) 的错误……

查询 Rails 的 API 发现可以在 controller 里添加 skip_forgery_protection 跳过 csrf 验证。我想问问各位大神有没有能保留 csrf 验证的方法?

1 Floor has deleted

额,自己顶一个

好奇你是怎么单独拿到 token 的。如果你从其他表单中提取 token,就会有问题

API 模式是不需要 CSRF Token 的,可以考虑直接关掉。

You need to Sign in before reply, if you don't have an account, please Sign up first.