【发布时间】:2021-03-11 09:54:14
【问题描述】:
我刚刚将我的第一个应用程序部署到 heroku,它使用了 Rails API(后端)和 React 前端。当我部署我的应用程序时,每当我尝试发出涉及使用 JSON Web 令牌 (JWT) 的请求时,都会收到 401 未经授权的错误。我在我的应用程序中从本地存储发送令牌,当我在我的开发环境中发送它时一切正常。我只在生产中遇到这个问题。
当我从前端发出 fetch 请求并通过 JWT 发送到后端时,我在 heroku 服务器日志中收到以下消息:
2020-11-29T04:45:31.742735+00:00 app[web.1]: I, [2020-11-29T04:45:31.742670 #4] INFO -- : [f3c19eae-e431-4c9f-b93b-7499797f2c03] [active_model_serializers] Rendered ActiveModel::Serializer::Null with Hash (0.13ms)
2020-11-29T04:45:31.742984+00:00 app[web.1]: I, [2020-11-29T04:45:31.742919 #4] INFO -- : [f3c19eae-e431-4c9f-b93b-7499797f2c03] Filter chain halted as :authorized rendered or redirected
2020-11-29T04:45:31.744091+00:00 app[web.1]: I, [2020-11-29T04:45:31.744019 #4] INFO -- : [f3c19eae-e431-4c9f-b93b-7499797f2c03] Completed 401 Unauthorized in 2ms (Views: 0.7ms | Allocations: 218)
另一个奇怪的事情是,我在我的 React 前端收到一条错误消息以及 401 状态错误,告诉我请登录,即使我登录了我的应用程序以接收令牌在我尝试发出另一个获取请求之前从我的后端获取
下面我将发布其他相关代码sn-ps,以便您可以看到我正在尝试做什么
这是我前端发送请求的代码
addToCart = () =>{
//make a fetch request to add the item in the customer's current cart
fetch("https://health-and-fit-store-api.herokuapp.com/cart_products",{
method:"POST",
headers:{
"Authorization": localStorage.token,
"Content-Type":"application/json",
Accept:"application/json"
},
body:JSON.stringify({
productId :this.props.id
})
})
.then(res => res.json())
.then(data => {
this.props.addToCart(data)
toast.dark(`Added ${data.product.name.toLowerCase()} to your cart`)
})
}
这是我的 Rails API 中接收请求的代码
before_action :authorized, only: [:create,:delete]
def create
#will be receiving token in fetch request
#use the of the current cart and the product id passed in by the post request
current_cart = @customer.carts.find_by(checked_out:false)
product = Product.find(params[:productId])
new_cart_product = CartProduct.create(cart:current_cart,product:product, quantity:1)
render json: new_cart_product
end
这是我用来设置 JWT 的应用程序控制器的代码
class ApplicationController < ActionController::API
def encode_token(payload)
# should store secret in env variable
JWT.encode(payload, ENV['jwt_encode_string'])
#byebug
end
def auth_header
# { Authorization: 'Bearer <token>' }
request.headers['Authorization']
end
def decoded_token
if auth_header
token = auth_header
# header: { 'Authorization': '<token>' }
begin
JWT.decode(token, ENV['jwt_encode_string'], true, algorithm: 'HS256')
rescue JWT::DecodeError
nil
end
end
end
def logged_in_customer
if decoded_token
customer_id = decoded_token[0]['customer_id']
@customer = Customer.find_by(id: customer_id)
end
end
def logged_in?
!!logged_in_customer
end
def authorized
render json: { error_message: 'Please log in' }, status: :unauthorized unless logged_in?
end
end
如果有人可以帮助我解决这个问题,我将不胜感激,我已经被困了好几天了。另请注意,我已在 StackOverflow 上查看了涉及此问题的所有其他帖子,并且已经用尽了我能想到的各种 Google 搜索。
【问题讨论】:
-
确保
localStorage.tokeen包含Bearer前缀。"Authorization": localStorage.token,是"Authorization": Bearer XXXX -
我尝试使用 Bearer 前缀,如下所示:
"Authorization": `Bearer ${localStorage.token},但结果仍然是 401 Unauthorized。 -
jsonapi 和 jwt 使用哪个 gem?
-
我用的是jwt,但我想我可能已经意识到问题出在哪里了。我将用于在开发环境中的 environmnet 变量中创建 JWT 的字符串存储在我的开发环境中,并意识到我没有在 heroku 中这样做。所以我会更新它并再试一次,让你知道结果是什么。
-
我使用 heroku 的 config vars 设置创建了环境变量,并确认我可以在使用 ``` ENV["variable_name"]`` 时正确引用它们,即使进行了这个更改,我仍然得到 401每当我在请求登录我的应用后提出任何请求时都会出现未经授权的错误。
标签: ruby-on-rails heroku jwt