ruby-on-rails - 无法使用 JWT 身份验证在 Rails 后端创建用户对象
问题描述
我正在尝试使用 JWT 身份验证在 Rails PostgreSQL 数据库中创建用户对象。当我从我的 React 前端触发 create user 方法时,用户不是在后端创建的,我怀疑这与我的控制器的设置方式有关。
这是我的 Rails 后端中的用户控制器:
class Api::V1::UsersController < ApplicationController
before_action :find_user, only: [:show]
skip_before_action :authorized, only: [:index, :create]
def index
@users = User.all
render json: @users
end
def show
render json: @user
end
def create
@user = User.create(user_params)
if @user.valid?
@token = encode_token(user_id: @user.id)
render json: { user: UserSerializer.new(@user), jwt: @token }, status: :created
else
render json: {error: "Could not create user"}, status: :unprocessible_entity
end
end
end
private
def user_params
params.permit(:username, :password)
end
def find_user
@user = User.find(params[:id])
end
这是我的 JWT 的“身份验证”控制器:
class Api::V1::AuthController < ApplicationController
skip_before_action :authorized, only: [:create]
def create # POST /api/v1/login
@user = User.find_by(username: user_login_params[:username])
if @user && @user.authenticate(user_login_params[:password])
@token = encode_token({ user_id: @user.id })
render json: { user: UserSerializer.new(@user), jwt: @token }, status: :accepted
else
render json: { message: 'Invalid username or password' }, status: :unauthorized
end
end
private
def user_login_params
params.require(:user).permit(:username, :password)
end
end
还有我的应用程序控制器(我怀疑问题就在这里,并且与我编码和解码令牌的方式有关):
class ApplicationController < ActionController::API
before_action :authorized
def encode_token(payload)
JWT.encode(payload, ENV["jwt_secret"])
end
def auth_header
request.headers['Authorization']
end
def decoded_token
if auth_header()
token = auth_header.split(' ')[1]
begin
JWT.decode(token, ENV["jwt_secret"], true, algorithm: 'HS256')
rescue JWT::DecodeError
nil
end
end
end
def current_user
if decoded_token()
user_id = decoded_token[0]['user_id']
@user = User.find_by(id: user_id)
else
nil
end
end
def logged_in?
!!current_user
end
def authorized
render json: { message: 'Please log in' }, status: :unauthorized unless logged_in?
end
end
从我的前端,我使用 fetch 方法来 POST 到 /users/ 端点,如下所示:
export const signupUser = (username, password) => {
return(dispatch) => {
const data = {user: {username, password} }
fetch('http://localhost:3000/api/v1/users',{
method: 'POST',
headers: {
'Content-Type': 'application/json',
Accept: 'application/json'
},
body: JSON.stringify(data)
})
.then(r=>r.json())
.then(r=>{
localStorage.setItem('jwt', r.jwt)
dispatch({
type: SET_CURRENT_USER,
payload: r.user
})
})
}
}
抱歉,这是冗长的。我想包括所有必要的代码来解决这个问题。任何援助将不胜感激。
解决方案
我注意到当您使用函数创建用户时,您没有保存用户对象。请使用to方法检查app/controllers/api/v1/users_controller.rb
并修改以下内容valid
save
def create
@user = User.create(user_params)
if @user.valid?
@token = encode_token(user_id: @user.id)
render json: { user: UserSerializer.new(@user), jwt: @token }, status: :created
else
render json: {error: "Could not create user"}, status: :unprocessible_entity
end
end
将行更改@user.valid?
为@user.save
def create
@user = User.create(user_params)
if @user.save
@token = encode_token(user_id: @user.id)
render json: { user: UserSerializer.new(@user), jwt: @token }, status: :created
else
render json: {error: "Could not create user"}, status: :unprocessible_entity
end
end
请注意 .valid? 用于验证和检查是否有任何错误,.save 用于保存。您只是在检查验证而不是实际保存,验证会自动发生,因此这里不需要此方法。
推荐阅读
- go - nil 的类型是什么?
- javascript - Axios 拦截器 - ReferenceError: Data is not defined
- javascript - Unity C#如何正确加载托管DLL?
- wordpress - 致命错误:未捕获 Mpdf\MpdfException for Send PDF for Contact Form 7
- javascript - 如何将我的 JavaScript 代码放在 url 上,以便任何人都可以链接到他们的 HTML 文件?
- python - 如何通过 python 中的 Google Drive API 重命名谷歌电子表格?
- powerbi - 获取报表中某一列的总计
- php - 如何从 textarea 中的 @foreach 循环呈现 html
- javascript - IE11 上的 eventListener 的 JS 问题 - 幻灯片导航不起作用
- html - css中重叠元素而不使用网格