module Api
module V1
class PostsController < ApplicationController
before_action :set_post, only: [:show, :update, :destroy]

# GET /api/v1/posts
def index
@posts = Post.all
render json: @posts
end

# GET /api/v1/posts/:id
def show
render json: @post
end

# POST /api/v1/posts
def create
@post = Post.new(post_params)
if @post.save
render json: @post, status: :created
else
render json: @post.errors, status: :unprocessable_entity
end
end

# PUT /api/v1/posts/:id
def update
if @post.update(post_params)
render json: @post
else
render json: @post.errors, status: :unprocessable_entity
end
end

# DELETE /api/v1/posts/:id
def destroy
@post.destroy
head :no_content
end

private

def set_post
@post = Post.find(params[:id])
end

def post_params
params.require(:post).permit(:title, :content)
end
end
end
end
```

更新命名空間的路由

要將 API 請求路由到命名空間控制器,請修改以config/routes.rbapi/v1添加命名空間

```
Rails.application.routes.draw do
namespace :api do
namespace :v1 do
resources :posts
end
end
end
```

干得好!您已經(jīng)成功地設(shè)置了一個(gè)簡單的Rails API,用于處理Post資源上的基本CRUD(創(chuàng)建、讀取、更新、刪除)操作。根據(jù)您的需求,您可以通過添加身份驗(yàn)證、驗(yàn)證、錯(cuò)誤處理、分頁等來進(jìn)一步擴(kuò)展。

如何開始使用 Ruby on Rails 構(gòu)建一個(gè)安全的API?

設(shè)置您的 Rails 應(yīng)用程序

讓我們首先創(chuàng)建一個(gè)新的 Ruby on Rails 應(yīng)用程序。打開終端并運(yùn)行以下命令:

rails new secure_api

此命令創(chuàng)建一個(gè)名為“ secure_api ”的新 Rails 應(yīng)用程序。

創(chuàng)建 API 端點(diǎn)

我們將創(chuàng)建一個(gè)帶有單個(gè)端點(diǎn)的簡單 API 來管理“todos”。讓我們?yōu)椤癟odo”資源生成一個(gè)腳手架(scaffold)。

rails generate scaffold Todo title:string completed:boolean

此命令生成“Todo”資源的控制器、模型和視圖。我們不會在 API 中使用視圖,但 Rails 默認(rèn)會創(chuàng)建它們。

配置路由

接下來,打開config/routes.rb文件并配置 API 的路由:

# config/routes.rb

Rails.application.routes.draw do
namespace :api, defaults: { format: :json } do
namespace :v1 do
resources :todos
end
end
end

此配置在/api/v1命名空間下設(shè)置了API端點(diǎn)。

實(shí)施基本身份驗(yàn)證

身份驗(yàn)證可確保只有授權(quán)用戶才能訪問您的 API。在此示例中,我們將使用 Devise gem 進(jìn)行用戶身份驗(yàn)證。

首先,將 Devise 添加到 Gemfile 中并運(yùn)行:

gem 'devise'

現(xiàn)在,安裝 Devise 并生成 User 模型:

rails generate devise:install
rails generate devise User

實(shí)施基本授權(quán)

授權(quán)定義用戶可以在您的 API 中執(zhí)行哪些操作。我們將使用 CanCanCan gem 進(jìn)行基于角色的授權(quán)。

將 CanCanCan 添加到您的 Gemfile 并運(yùn)行bundle install

gem 'cancancan'

創(chuàng)建用于生成授權(quán)規(guī)則的能力模型:

rails generate cancan:ability

ability.rb文件中定義角色和授權(quán)規(guī)則:

# app/models/ability.rb

class Ability
include CanCan::Ability

def initialize(user)
user ||= User.new

if user.admin?
can :manage, :all
else
can :read, Todo
can :create, Todo
can :update, Todo, user_id: user.id
can :destroy, Todo, user_id: user.id
end
end
end

驗(yàn)證和清理輸入

輸入驗(yàn)證和清理對于安全性至關(guān)重要。FastAPI是一個(gè)因其特性而聞名的Python框架,但在Rails中,我們則采用標(biāo)準(zhǔn)的Rails驗(yàn)證方法。讓我們驗(yàn)證我們的Todo模型。

打開app/models/todo.rb文件并添加驗(yàn)證規(guī)則:

# app/models/todo.rb

class Todo < ApplicationRecord
validates :title, presence: true
validates :completed, inclusion: { in: [true, false] }
end

測試您的安全 API

既然我們已經(jīng)構(gòu)建了一個(gè)具備身份驗(yàn)證、授權(quán)以及輸入驗(yàn)證功能的安全Ruby on Rails API,接下來就該對其進(jìn)行測試了。

啟動(dòng)你的 Rails 服務(wù)器:

rails server

您可以使用Postman curl 等工具來測試您的 API 端點(diǎn)。例如,要?jiǎng)?chuàng)建一個(gè)新的待辦事項(xiàng):

curl -X POST -H "Content-Type: application/json" -d '{"title": "Buy groceries", "completed": false}' http://localhost:3000/api/v1/todos

確保測試不同的場景,包括身份驗(yàn)證、授權(quán)和輸入驗(yàn)證,以確保您的 API 安全且按預(yù)期運(yùn)行。

在 Ruby on Rails 中實(shí)現(xiàn)身份驗(yàn)證

身份驗(yàn)證是在 Ruby on Rails 中構(gòu)建安全 API 的一個(gè)重要方面。它允許用戶驗(yàn)證自己的身份并授予他們對受保護(hù)資源的訪問權(quán)限。借助 Rails,可以使用DeviseSorcery等 gem 輕松實(shí)現(xiàn)身份驗(yàn)證。

這些gem提供了預(yù)構(gòu)建的身份驗(yàn)證功能,為我們節(jié)省了大量的時(shí)間和精力。接下來,我們來看一個(gè)使用Devise來驗(yàn)證用戶身份的示例。首先,我們需要安裝 Devise gem,將其添加到 Gemfile 中并運(yùn)行捆綁安裝命令。

# Gemfile
# Add Devise gem to your Rails application
gem 'devise'

# Terminal
# Run bundle install to install the gem
bundle install

現(xiàn)在,讓我們創(chuàng)建一個(gè)用戶模型并使用 Devise 設(shè)置身份驗(yàn)證:

# Generate a User model with Devise
rails generate devise User

# Run the database migration
rails db:migrate

接下來,您可以說明如何使用 Devise 通過身份驗(yàn)證來保護(hù)您的 API 端點(diǎn)。在控制器中,您可以使用before_action過濾器來確保只有經(jīng)過身份驗(yàn)證的用戶才能訪問特定資源:

# app/controllers/api/v1/posts_controller.rb
class Api::V1::PostsController < ApplicationController
before_action :authenticate_user!

def index
posts = Post.all
render json: posts
end

def create
# Create a new post
end

# Other actions...

end

要向特定模型(例如用戶)添加身份驗(yàn)證,我們可以運(yùn)行railsgenerate devise MODEL_NAME命令。最后,我們需要通過將以下行添加到我們的config/routes.rb文件中來配置路由來處理身份驗(yàn)證路徑devise_for: users:就是這樣簡單!僅僅通過幾個(gè)步驟,我們就成功地在Ruby on Rails API中利用Devise實(shí)現(xiàn)了身份驗(yàn)證功能。

基于令牌的身份驗(yàn)證

為了確保只有授權(quán)用戶才能訪問某些資源,您可以使用基于令牌的身份驗(yàn)證,用戶在成功登錄后會收到一個(gè)令牌,然后將該令牌用于后續(xù)的 API 請求。

要實(shí)現(xiàn)此目的,請將以下 gem 添加到 gemfile 并運(yùn)行bundle install

# Gemfile
gem 'devise_token_auth'

配置 Devise 以進(jìn)行基于令牌的身份驗(yàn)證:

# config/initializers/devise_token_auth.rb

Devise.setup do |config|
config.secret_key = 'your_secret_key' # Replace with a secure secret key
end

創(chuàng)建具有令牌身份驗(yàn)證的用戶模型:

generate devise_token_auth:install User auth

遷移數(shù)據(jù)庫:

rails db:migrate

使用身份驗(yàn)證保護(hù)您的 API 路由before_action

# app/controllers/api/v1/base_controller.rb

module Api
module V1
class BaseController < ApplicationController
before_action :authenticate_user!

# Your API actions go here
end
end
end

使用 Tiddle 進(jìn)行多令牌身份驗(yàn)證

安裝Tiddle開始,將 Tiddle 添加到您的 Gemfile 并運(yùn)行bundle install

# Gemfile
gem 'tiddle'

配置Tiddle的下一步是通過創(chuàng)建一個(gè)初始化程序來進(jìn)行。請運(yùn)行以下命令以生成初始化程序文件:

rails generate tiddle:install

這將生成一個(gè)名為config/initializers/tiddle.rb的文件。請打開此文件,并根據(jù)您的具體需求進(jìn)行相應(yīng)的配置。您可以設(shè)置令牌過期時(shí)間和用戶模型名稱等選項(xiàng)。例如:

Tiddle.configure do |config|
config.token_lifetime = 1.week
config.user_identifier = :email
end

更新用戶模型 Tiddle 要求您的用戶模型具有一些特定的方法。在您的用戶模型(例如,app/models/user.rb)中,包含該Tiddle::TokenIssuer模塊并定義所需的方法:

class User < ApplicationRecord
include Tiddle::TokenIssuer

# Define the following methods:
def self.find_by_token(token)
# Implement logic to find a user by token
end

def self.build_from_token(token)
# Implement logic to build a user from a token
end
end

現(xiàn)在,讓我們在您的API控制器中實(shí)現(xiàn)身份驗(yàn)證功能。以下是如何保護(hù)特定端點(diǎn)的示例:

class ApiController < ApplicationController
before_action :authenticate_user!

def secure_endpoint
# Your secure endpoint logic goes here
end
end

為了生成和驗(yàn)證用于身份驗(yàn)證的令牌,您可以在登錄操作中使用Tiddle的create_and_return_token方法,并在用戶注銷時(shí)使用Tiddle.expire_token方法。以下是登錄操作的示例:

class SessionsController < ApplicationController
def create
user = User.find_by(email: params[:email])

if user&.authenticate(params[:password])
token = Tiddle.create_and_return_token(user, request)
render json: { auth_token: token }
else
render json: { error: 'Invalid credentials' }, status: :unauthorized
end
end

def destroy
Tiddle.expire_token(current_user, request)
head :no_content
end
end

最后,測試您的 API 以確保一切按預(yù)期工作。您應(yīng)該能夠使用生成的令牌對用戶進(jìn)行身份驗(yàn)證并保護(hù)您的 API 端點(diǎn)。

處理權(quán)限和授權(quán)

為了確保只有經(jīng)過授權(quán)的用戶才能訪問API的特定部分,對權(quán)限和授權(quán)進(jìn)行有效處理是至關(guān)重要的。在 Ruby on Rails 中,一種流行的方法是使用名為“?CanCanCan?”的 gem?。這個(gè) gem 允許您定義應(yīng)用程序中每個(gè)用戶角色的能力和權(quán)限。通過設(shè)置能力,您可以輕松控制每個(gè)用戶可以對不同資源執(zhí)行哪些操作。例如,您可以定義只有管理員才能刪除記錄,而普通用戶只能查看或編輯記錄。您可以通過創(chuàng)建一個(gè)能力文件來實(shí)現(xiàn)這一點(diǎn),在該文件中使用簡單的代碼片段定義每個(gè)角色的能力。

以下是您將如何實(shí)現(xiàn)它:

將 CanCanCan gem 添加到您的 Gemfile 中并運(yùn)行bundle install以安裝它:

# Gemfile
gem 'cancancan'

在 Rails 應(yīng)用程序中生成 User 模型和 Post 模型(或您想要保護(hù)的任何資源):

rails generate model User name:string role:string
rails generate model Post title:string content:text user:references
rails db:migrate

使用“cancancan”在能力模型中定義用戶角色和能力。ability.rb在目錄中創(chuàng)建文件app/models

# app/models/ability.rb
class Ability
include CanCan::Ability

def initialize(user)
user ||= User.new # Guest user (not logged in)

if user.admin?
can :manage, :all # Admins can manage all resources
else
can :read, Post # Regular users can read posts
can :create, Post # Regular users can create posts
can :update, Post, user_id: user.id # Regular users can update their own posts
end
end
end

在您的控制器中,使用 CanCanCan 根據(jù)用戶角色授權(quán)操作:

# app/controllers/api/v1/posts_controller.rb
class Api::V1::PostsController < ApplicationController
load_and_authorize_resource # Loads the Post resource and authorizes actions

def index
render json: @posts
end

def create
# Create a new post
if @post.save
render json: @post, status: :created
else
render json: @post.errors, status: :unprocessable_entity
end
end

def update
# Update an existing post
if @post.update(post_params)
render json: @post
else
render json: @post.errors, status: :unprocessable_entity
end
end

# Other actions...

private

def post_params
params.require(:post).permit(:title, :content)
end
end

保護(hù)敏感數(shù)據(jù)

加密敏感數(shù)據(jù)

為了在 Ruby on Rails 中構(gòu)建安全的 API,保護(hù)敏感數(shù)據(jù)至關(guān)重要。實(shí)現(xiàn)這一目標(biāo)的一種方法是實(shí)施適當(dāng)?shù)纳矸蒡?yàn)證和授權(quán)機(jī)制。通過要求用戶在訪問某些數(shù)據(jù)或執(zhí)行特定操作前進(jìn)行身份驗(yàn)證,我們能夠確保只有獲得授權(quán)的個(gè)人才能訪問敏感信息。這可以通過使用像前面提到的Devise這樣的工具來實(shí)現(xiàn),它提供了一個(gè)簡單而靈活的身份驗(yàn)證解決方案。此外,使用bcrypt等安全哈希算法對密碼等敏感數(shù)據(jù)進(jìn)行加密也很重要。以純文本形式存儲密碼是一個(gè)很大的禁忌,因?yàn)檫@會使密碼容易被盜竊和濫用。通過對密碼進(jìn)行哈希處理,我們可以確保即使攻擊者獲取了對存儲數(shù)據(jù)的訪問權(quán)限,他們也無法逆向工程出原始密碼。以下是如何使用bcrypt安全存儲和驗(yàn)證密碼的示例:

# Gemfile
gem 'bcrypt'

# app/models/user.rb
class User < ApplicationRecord
has_secure_password
end

# app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
def create
user = User.find_by(email: params[:email])
if user&.authenticate(params[:password])
# Successful authentication
else
# Invalid credentials
end
end
end

通過實(shí)施這些措施,我們可以更好地保護(hù) Ruby on Rails API 中的敏感數(shù)據(jù),并確保只有授權(quán)用戶才能訪問它。

防止 API 濫用和攻擊

在 Ruby on Rails 中構(gòu)建安全 API 的一個(gè)重要方面是采取措施防止?jié)撛诘臑E用和攻擊。實(shí)現(xiàn)此目的的一種常見方法是實(shí)施速率限制。通過對用戶或IP地址在特定時(shí)間范圍內(nèi)所能發(fā)出的請求數(shù)量進(jìn)行限制,我們可以有效地降低遭受暴力破解攻擊或因流量過大而導(dǎo)致服務(wù)器崩潰的風(fēng)險(xiǎn)。下面的代碼片段演示了如何使用“?rack-attack?”gem在 Ruby on Rails 中實(shí)現(xiàn)速率限制:

# config/initializers/rack_attack.rb

Rack::Attack.throttle('requests per IP', limit: 100, period: 1.minute) do |request|
request.ip
end

在上面的示例中,我們定義了名為“每個(gè) IP 的請求數(shù)”的限制規(guī)則。它將 IP 地址可以發(fā)出的請求數(shù)量限制為每分鐘 100 個(gè)請求。這個(gè)簡單的措施可以防止個(gè)人 IP 地址的潛在濫用,從而幫助保護(hù)我們的 API。

使用最小權(quán)限 CORS 策略保護(hù)您的生產(chǎn)環(huán)境

在將Web應(yīng)用程序部署到生產(chǎn)環(huán)境時(shí),跨源資源共享(CORS)是一個(gè)需要重點(diǎn)考慮的安全功能,它決定了哪些域可以訪問您的應(yīng)用程序資源。建立遵循最小特權(quán)原則的 CORS 策略對于最大限度地減少潛在的安全風(fēng)險(xiǎn)至關(guān)重要。幸運(yùn)的是,rack-corsRuby on Rails 中的 gem 提供了一個(gè)強(qiáng)大的工具來幫助您實(shí)現(xiàn)這一目標(biāo)。

在本節(jié)中,我們將討論如何使用 gem 在 Ruby on Rails 應(yīng)用程序的生產(chǎn)環(huán)境中設(shè)置 CORS 策略rack-cors。我們將強(qiáng)調(diào)最小權(quán)限原則,以確保您的應(yīng)用程序的安全。

什么是最小特權(quán)原則?

最小權(quán)限原則是一個(gè)基本的安全概念,它將用戶和應(yīng)用程序的訪問權(quán)限限制為執(zhí)行其任務(wù)所需的最小權(quán)限。在CORS的語境下,這意味著我們應(yīng)當(dāng)僅允許特定的、必要的域來訪問您的資源,同時(shí)阻止所有其他來源的訪問。

設(shè)置 CORS 策略

以下是使用 gem 建立遵循最小權(quán)限原則的 CORS 策略的步驟:

安裝 rack-cors

首先,您需要在Rails項(xiàng)目的Gemfile文件中添加rack-cors gem,并運(yùn)行bundle install命令來安裝它:

gem 'rack-cors'

配置 CORS

在 Rails 應(yīng)用程序中,您可以在config/application.rb文件中定義 CORS 策略。打開此文件并找到該Rails.application.configure do塊。添加以下配置以設(shè)置基本 CORS 策略:

config.middleware.insert_before 0, Rack::Cors do
allow do
origins 'https://your-allowed-domain.com' # Replace with your production domain
resource '*', headers: :any, methods: [:get, :post, :put, :patch, :delete]
end
end

在此示例中,我們指定僅允許來自“https://your-allowed-domain.com”的請求。所有其他來源均被拒絕訪問。同時(shí),我們還明確指定了允許哪些HTTP方法(如GET、POST、PUT、PATCH、DELETE),并且允許攜帶任何請求頭信息。

定制您的政策

上面的示例提供了基本的 CORS 策略。根據(jù)應(yīng)用程序的要求,您可以通過添加更多源、方法或標(biāo)頭來進(jìn)一步自定義它,以匹配您的特定用例。

測試您的 CORS 策略

在部署到生產(chǎn)之前,必須在不同環(huán)境中徹底測試 CORS 策略,以確保其行為符合預(yù)期。確保您的應(yīng)用程序僅對來自允許來源的請求作出響應(yīng),并拒絕來自未經(jīng)授權(quán)域的訪問請求。

清理用戶輸入

另一個(gè)至關(guān)重要的做法是驗(yàn)證用戶輸入,并對任何用戶提供的數(shù)據(jù)進(jìn)行清理,以此來防范SQL注入、跨站點(diǎn)腳本(XSS)等惡意攻擊。Ruby on Rails 提供了用于輸入驗(yàn)證和過濾的內(nèi)置機(jī)制,因此請確保正確使用它。

為此,請使用 Rails 的內(nèi)置驗(yàn)證方法進(jìn)行輸入驗(yàn)證。

# app/models/user.rb

class User < ApplicationRecord
validates :email, presence: true, uniqueness: true, format: { with: /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i }
validates :password, presence: true, length: { minimum: 8 }

# Add any other validations as needed
end

要清理用戶提供的數(shù)據(jù),可以使用sanitize方法 或sanitize_sql方法來防止 SQL 注入:

# app/controllers/api/v1/users_controller.rb

module Api
module V1
class UsersController < BaseController
def create
# Sanitize user input
safe_name = ActiveRecord::Base.sanitize(params[:name])

# Your code here
end
end
end
end

此外,建議對所有 API 通信使用 HTTPS,以保護(hù)敏感數(shù)據(jù)并防止竊聽。通過遵循這些最佳實(shí)踐并及時(shí)了解最新的安全補(bǔ)丁,您可以在 Ruby on Rails 中構(gòu)建安全可靠的 API。

結(jié)論

API 對于實(shí)現(xiàn)應(yīng)用程序之間的數(shù)據(jù)交換至關(guān)重要,它們有多種形式,包括公共、私有、合作伙伴和復(fù)合 API。在眾多的可用協(xié)議中,REST憑借其簡單性、靈活性以及可擴(kuò)展性而顯得尤為突出,因此成為了構(gòu)建API的熱門選擇。Ruby on Rails非常適合用于創(chuàng)建RESTful API,因?yàn)樗旧砭褪腔赗EST原則構(gòu)建的,并且為處理常見的API任務(wù)提供了強(qiáng)大的內(nèi)置支持。

通過實(shí)施最佳實(shí)踐,例如對敏感數(shù)據(jù)使用環(huán)境變量以及應(yīng)用最小權(quán)限原則,您可以顯著降低漏洞風(fēng)險(xiǎn)。

Ruby on Rails 為構(gòu)建安全高效、可擴(kuò)展且易于維護(hù)的 API 提供了強(qiáng)大、靈活的基礎(chǔ)。無論您是與Ruby on Rails的專業(yè)公司合作,還是與小型開發(fā)團(tuán)隊(duì)攜手,對于旨在打造高質(zhì)量API服務(wù)的開發(fā)者而言,Ruby on Rails都是一個(gè)極為出色的選擇。

原文鏈接:https://escape.tech/blog/ruby-on-rails-security-guide/

上一篇:

檢測AI圖像的網(wǎng)站及其應(yīng)用

下一篇:

荷蘭電信公司KPN如何通過API建立新的連接
#你可能也喜歡這些API文章!

我們有何不同?

API服務(wù)商零注冊

多API并行試用

數(shù)據(jù)驅(qū)動(dòng)選型,提升決策效率

查看全部API→
??

熱門場景實(shí)測,選對API

#AI文本生成大模型API

對比大模型API的內(nèi)容創(chuàng)意新穎性、情感共鳴力、商業(yè)轉(zhuǎn)化潛力

25個(gè)渠道
一鍵對比試用API 限時(shí)免費(fèi)

#AI深度推理大模型API

對比大模型API的邏輯推理準(zhǔn)確性、分析深度、可視化建議合理性

10個(gè)渠道
一鍵對比試用API 限時(shí)免費(fèi)