Devise-JWT:使用cURL,我可以看到一个Authorization标头使用Axios / Fetch没有授权标头 奖金

问题描述

我在Devise和Devise-JWT上有一个非常典型的Rails后端。当我向端点/users/sign_in发出原始cURL请求时,可以在标头中看到它正在设置带有令牌的Authorization标头。

当我在React前端上执行相同的请求(位于不同的端口,因此需要跨源配置)时,我在结果中看到的唯一标头是cache-control和content-type。

现在,我已经安装了“ cors” gem。我创建了一个名为config/initializers/cors.rb的初始化程序,并将此配置放入其中:

Rails.application.config.middleware.insert_before 0,Rack::Cors do
    allow do
        origins '*'
        resource('*',headers: :any,expose: ["Authorization"],methods: :any
        )
    end
end

但是,当我在React前端发出请求时,没有看到Authorization标头。

我可以看到Rails正在响应302重定向。这是问题的一部分吗?我是否需要配置设备以停止响应302?

我完全不知道可能是什么问题。

如果您观察到下面的屏幕快照,则通过普通格式登录以正常方式登录会给我一个Authorization标头,但是如果我通过AJAX进行登录,则没有标头。

This image shows that there is an Authorization header when hitting the /users/sign_in endpoint normally with a non-AJAX request

这是前端(AJAX)代码,它没有给我任何授权标头,只有“ cache-control”和“ content-type”:

async function submitLogin(email,password) {
    let formData = new FormData();

    formData.append("user[email]",email)
    formData.append("user[password]",password)

    let result = await Axios.post(`${process.env.API_URL}/users/sign_in`,formData,{maxRedirects: 0})

    console.log(result)
}

结果:

enter image description here

解决方法

免责声明:这不是您问题的100%答案,但是肯定可以!


如果在您的项目中devise-jwt不是必需的,我建议您遵循我在my Rails 6 / React template中所做的事情:

  1. 配置您的项目路由,以覆盖Devise的会话路由,例如I did in my template project
  2. 重写Devise的SessionController,以使其以JSON格式响应并返回JWT:
# frozen_string_literal: true

class SessionsController < Devise::SessionsController
  clear_respond_to
  respond_to :json

  def create
    super do |resource|
      if user_signed_in?
        resource.token = JwtWrapper.encode(user_id: current_user.id)
      end
    end
  end
end
  1. JwtWrapper中添加app/helpers/jwt_wrapper.rb
# frozen_string_literal: true

module JWTWrapper
  extend self

  def encode(payload,expiration = nil)
    expiration ||= Rails.application.secrets.jwt_expiration_hours

    payload = payload.dup
    payload['exp'] = expiration.to_i.hours.from_now.to_i

    JWT.encode payload,Rails.application.secrets.jwt_secret
  end

  def decode(token)
    decoded_token = JWT.decode token,Rails.application.secrets.jwt_secret

    decoded_token.first
  rescue StandardError
    nil
  end
end

现在,您将在响应正文中获得有效的JWT。

奖金

我建议您看看restful-json-api-client package,它可以handle JWT for you在响应中寻找token属性并将其存储并传递给您的请求。

它也handle JWT renewal automatically!,所以当您的API答复401错误时,如果您配置了续订路径,它将尝试续订JWT。如果成功,它将使用新的JWT重做查询,并且对您的应用程序是透明的;否则,如果无法续订,它将失败返回给您的应用程序,以便您可以执行一些操作,例如将用户重定向到登录名页面。

希望这次我能回答您更多的问题。 ?

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...