Невозможно создать пользовательский объект в бэкэнде rails, используя аутентификацию JWT - PullRequest
0 голосов
/ 14 октября 2019

Я пытаюсь создать объекты User в базе данных PostgreSQL с использованием JWT-аутентификации. Когда я запускаю метод create user из моего интерфейса React, пользователь не создается в бэкэнде, и я подозреваю, что это как-то связано с настройкой моих контроллеров.

Вот мой пользовательский контроллер в моем бэкэнде 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

Вот мой 'auth' контроллер для 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

Из моего внешнего интерфейса я использую метод выборки для POST в / users / endpoint, например так:

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
      })
    })
  }
}

Извинения, чтоэто многословно. Я хотел включить весь код, необходимый, чтобы понять это. Любая помощь будет оценена.

1 Ответ

0 голосов
/ 15 октября 2019

Я заметил, что вы не сохраняете свой пользовательский объект, когда используете функцию для создания пользователя. Пожалуйста, отметьте 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

Пожалуйста, обратите внимание. используется для проверки и проверки наличия какой-либо ошибки, а .save для ее сохранения. Вы просто проверяете проверку и не сохраняете ее, проверка происходит автоматически, поэтому здесь нет необходимости в этом методе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...