reactjs - Rails API 用户身份验证接受来自 React 代理的 api 调用,但不直接来自主机 url
问题描述
我目前正在尝试部署一个 React 前端和 Rails API Web 应用程序。在开发中,我在 package.json 中设置了一个代理来与我的 API 进行通信。用户身份验证和 CRUD 操作一切正常。现在,当我进入生产环境时,我的用户 auth 告诉我,即使我有会话令牌,我也无权进行除了登录之外的任何呼叫。
我的应用程序控制器似乎挂断了:
class ApplicationController < ActionController::API
include ActionController::Cookies
before_action :authorize
def authorize
@current_user = User.find_by(id: session[:user_id])
render json: {error:["Not authorized"]}, status: :unauthorized unless @current_user
end
当我注销或执行其他操作时,我的 Ruby 终端会输出类似这样的内容
Started DELETE "/logout" for ::1 at 2021-09-08 14:20:06 -0400
Processing by SessionsController#destroy as HTML
[active_model_serializers] Rendered ActiveModel::Serializer::Null with Hash (0.12ms)
Filter chain halted as :authorize rendered or redirected
Completed 401 Unauthorized in 1ms (Views: 0.6ms | ActiveRecord: 0.0ms | Allocations: 203)
这是我的用户控制器:
class UsersController < ApplicationController
wrap_parameters format: []
skip_before_action :authorize, only: [:create]
def create
user = User.create(user_params)
if user.valid?
session[:user_id] = user.id
render json: user, status: :created
else
render json: {errors: user.errors.full_messages}, status: :unprocessable_entity
end
end
def show
user = @current_user
render json: user, status: :created
end
private
def user_params
params.permit(:email, :username, :password, :password_confirmation, :bio, :join_date)
end
我的会话控制器:
class SessionsController < ApplicationController
skip_before_action :authorize, only: [:create]
def create
user = User.find_by(username: params[:username])
if user&.authenticate(params[:password])
session[:user_id] = user.id
render json: user, status: :created
else
render json: { errors: ["Invalid username or password"] }, status: :unauthorized
end
end
def destroy
session.delete(:user_id)
head = :no_content
end
我的 fetch 调用都是相当基本的,比如:
function signin(username, password) {
setIsLoading(true);
fetch("http://localhost:3000/login", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ username, password }),
}).then((r) => {
setIsLoading(false);
if (r.ok) {
r.json().then((user) => {
setUser(user);
});
} else {
r.json().then((err) => setErrors(err.errors));
}
});
}
当我代理到 API URL 时一切正常但当我明确调用它时,为什么会发生这种情况session[:user_id]
?我花了几天时间尝试不同的东西,寻找解决方案......
解决方案
所以我的假设是,身份验证应该存储在一个 cookie 中,该 cookie 作为前端调用中的标头(隐式)传递,并且应该传递给 API。如果您 100% 确定代理在本地工作,那么我会看看您的生产设置有什么不同。
检查 cookie 标头是否正在发送到反应应用程序。检查 cookie 标头是否到达您的 rails 应用程序。
Cookie 可以具有安全设置,例如仅通过 HTTPS 发送或仅发送到特定域。您的生产设置可能会因您的 react 服务器或 rails 使用的默认安全设置而有所不同。
推荐阅读
- java - 如何使用 Java 和 Spring Boot 使用 XML 数据
- laravel - 如何在不损失图像质量的情况下调整图像大小?
- azure - Azure 自动化无法启动 vm,因为凭据已更改?
- javascript - 使用 node pkg 通过 npm config 创建可执行文件
- vue.js - 如何自动运行 NuxtJS 项目
- r - 如何从 JSON Response 中获取数据表
- javascript - 无法在 javascript 函数调用中将 JSON 对象作为第二个参数传递
- python - 他们有什么方法可以通过 python 和 librosa 转录大型音频文件吗?
- google-data-studio - 有没有办法动态过滤数据工作室报告?
- typescript - React Native - 打字稿问题