
NG是什么意思:深度解析與應(yīng)用
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ò)展。
設(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)行。
身份驗(yàn)證是在 Ruby on Rails 中構(gòu)建安全 API 的一個(gè)重要方面。它允許用戶驗(yàn)證自己的身份并授予他們對受保護(hù)資源的訪問權(quán)限。借助 Rails,可以使用Devise或Sorcery等 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)。
為了確保只有經(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
為了在 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)用戶才能訪問它。
在 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。
在將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-cors
Ruby 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。
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/