如何在仅限 Rails API 的应用程序中保持会话

问题描述 投票:0回答:1

我对 ruby on Rails 很陌生,我想将会话添加回 Rails 6 API 应用程序,以便我在会话中获得

current_cart
id,如果会话中不存在该 id,它将继续创建一个新的购物车并将 ID 存储在会话中。

  • 我想知道是否还有比重新添加会话更好的选择?即像使用 JWT 令牌一样。
  • 我正在关注 Rails 敏捷 Web 开发书,但我仅在 Rails API 模式下完成。

以下是我的申请.rb

# frozen_string_literal: true

require_relative 'boot'

require 'rails'
# Pick the frameworks you want:
require 'active_model/railtie'
require 'active_job/railtie'
require 'active_record/railtie'
require 'active_storage/engine'
require 'action_controller/railtie'
require 'action_mailer/railtie'
require 'action_mailbox/engine'
require 'action_text/engine'
require 'action_view/railtie'
require 'action_cable/engine'
require 'sprockets/railtie'
# require "rails/test_unit/railtie"

# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)

module DepotApi
  class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 6.1

    # skip verifying users on logout
    config.to_prepare do
      Devise::SessionsController.skip_before_action :verify_signed_out_user, only: :destroy
    end
    # Configuration for the application, engines, and railties goes here.
    #
    # These settings can be overridden in specific environments using the files
    # in config/environments, which are processed later.
    #
    # config.time_zone = "Central Time (US & Canada)"
    config.eager_load_paths << Rails.root.join('lib')

    # Only loads a smaller set of middleware suitable for API only apps.
    # Middleware like session, flash, cookies can be added back manually.
    # Skip views, helpers and assets when generating a new resource.
    config.api_only = true
    config.app_generators.scaffold_controller = :scaffold_controller

    # Middleware for ActiveAdmin
    config.middleware.use Rack::MethodOverride
    config.middleware.use ActionDispatch::Flash
    config.middleware.use ActionDispatch::Cookies
    config.middleware.use ActionDispatch::Session::CookieStore
  end
end

下面是我的 Line_items 控制器

# frozen_string_literal: true

class LineItemsController < ApiController
  include CurrentCart
  before_action :set_cart, only: [:create]
  before_action :set_line_item, only: %i[show update destroy]

  # GET /line_items
  # GET /line_items.json
  def index
    @line_items = LineItem.all
  end

  # GET /line_items/1
  # GET /line_items/1.json
  def show; end

  # POST /line_items
  # POST /line_items.json
  def create
    product = Product.find(params[:product_id])
    @line_item = @cart.add_product(product)

    if @line_item.save
      render :show, status: :created, location: @line_item
    else
      render json: @line_item.errors, status: :unprocessable_entity
    end
  end

  # Increasing quantity
  def add_quantity
    @line_item.quantity += 1
    @line_item.save
  end

  # decreasing  quantity
  def reduce_quantity
    @line_item.quantity > 1
    @line_item.quantity -= 1
    @line_item.save
  end

  # PATCH/PUT /line_items/1
  # PATCH/PUT /line_items/1.json
  def update
    if @line_item.update(line_item_params)
      render :show, status: :ok, location: @line_item
    else
      render json: @line_item.errors, status: :unprocessable_entity
    end
  end

  # DELETE /line_items/1
  # DELETE /line_items/1.json
  def destroy
    @line_item.destroy
  end

  private

  # Use callbacks to share common setup or constraints between actions.
  def set_line_item
    @line_item = LineItem.find(params[:id])
  end

  # Only allow a list of trusted parameters through.
  def line_item_params
    params.require(:line_item).permit(:product_id)
  end
end
  • @cart
    的值由我当前包含的模块设置。

下面是我设置会话的

Currentcart
模块

module CurrentCart
  private

  def set_cart
    @cart = Cart.find(session[:cart_id])
  rescue ActiveRecord::RecordNotFound
    @cart = Cart.create
    session[:cart_id] = @cart.id
  end
end

我所有的 API 控制器都从此扩展而来

apiController
除了
activeadmin

class ApiController < ActionController::API
end

下面是我的应用程序控制器

# frozen_string_literal: true

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by using :null_session
  protect_from_forgery with: :null_session

  before_action :configure_permitted_parameters, if: :devise_controller?

  rescue_from CanCan::AccessDenied do |_exception|
    render json: { error: 'Access denied' }, status: :forbidden
  end

  def authenticate_admin_user!
    if admin_user_signed_in?
      admin_root_path
    else
      new_admin_user_session_path
    end
  end

  protected

  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: %i[user_name email role])
    devise_parameter_sanitizer.permit(:sign_in, keys: %i[user_name email role])
  end
end
ruby-on-rails session jwt rails-api
1个回答
0
投票
  • 我终于找到了一个解决方案,为了连接两个应用程序,创建react应用程序和一个rails api,我需要首先将会话添加到rails api
    config.api_only = true
    config.app_generators.scaffold_controller = :scaffold_controller

    # Middleware for ActiveAdmin
    config.middleware.use Rack::MethodOverride
    config.middleware.use ActionDispatch::Flash
    config.middleware.use ActionDispatch::Cookies
    config.middleware.use ActionDispatch::Session::CookieStore
  • 然后在创建反应应用程序中我添加了这个设置

    package.json
    "proxy": "http://127.0.0.1:4000"

  • 然后我在前端的所有路线(创建反应应用程序)都更改如下

    http://127.0.0.1.400/products
    /products

  • 您可以从前端的会话中获取任何内容

© www.soinside.com 2019 - 2024. All rights reserved.