Rails API 用户身份验证接受来自 React 代理的 api 调用,但不直接来自主机 url
Posted
技术标签:
【中文标题】Rails API 用户身份验证接受来自 React 代理的 api 调用,但不直接来自主机 url【英文标题】:Rails API user auth accepts api calls from React proxy but not directly from host url 【发布时间】:2021-11-05 12:57:09 【问题描述】:我目前正在尝试部署一个 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 时一切正常,但当我明确调用它时,rails 找不到 session[:user_id]
进行身份验证时会发生这种情况?我花了几天时间尝试不同的东西,寻找解决方案......
【问题讨论】:
【参考方案1】:所以我的假设是,身份验证应该存储在一个 cookie 中,该 cookie 作为前端调用中的标头(隐式)传递,并且应该传递给 API。如果您 100% 确定代理在本地工作,那么我会看看您的生产设置有什么不同。
检查 cookie 标头是否正在发送到 React 应用程序。 检查 cookie 标头是否到达您的 rails 应用程序。
Cookie 可以具有安全设置,例如仅通过 HTTPS 发送或仅发送到特定域。您的生产设置可能会因您的 react 服务器或 rails 使用的默认安全设置而异。
【讨论】:
以上是关于Rails API 用户身份验证接受来自 React 代理的 api 调用,但不直接来自主机 url的主要内容,如果未能解决你的问题,请参考以下文章
SOA:Rails 多个客户端的用户身份验证和 api 授权
Rails API - 无法创建用户,密码是FILTERED并返回所有验证错误