首頁 >後端開發 >Golang >如何使用 Go、HTMX 和 Permit.io 在書店管理系統中設定授權

如何使用 Go、HTMX 和 Permit.io 在書店管理系統中設定授權

Mary-Kate Olsen
Mary-Kate Olsen原創
2024-12-01 02:08:10398瀏覽

授權在建立應用程式時非常重要,因為它決定了使用者在進行身份驗證後可以存取哪些操作和資源。

在本文中,我們將了解如何使用 Permit.io 實作授權。為了演示它,我們將使用 Golang 和 HTMX 建立一個簡單的書店應用程式(我是一個超級粉絲)。

先決條件

要完成本教程,應滿足以下先決條件:

  • Golang 的安裝以及對它的基本了解。
  • Permit.io 帳戶。
  • Docker 已安裝。
  • 對 HTML、HTTP 和 REST API 的基本了解。
  • PostgreSQL(資料庫)。
  • 熟悉 SQL。

專案範圍

  • 對於本次演示,我們將保持簡單。我們將有兩種使用者類型:管理員和標準使用者。兩者都將在 Permit.io 上註冊。登入後,資料庫將查詢 Permit.io 來確定使用者的角色並授權他們的操作。

所有使用者(包括管理員)都可以閱讀書籍。管理員還可以新增、刪除和更新圖書。標準使用者僅限於閱讀書籍。

本教學將引導您設定具有基本授權的書店應用程式。我們將實作:

  • 授權邏輯:使用 Permit.io 定義角色(管理員和標準使用者)來限製或授予對不同資源的存取權限。

  • 資料庫:設定 PostgreSQL 資料庫來儲存書籍和使用者資料。

  • 處理程序: 透過存取控制檢查實現檢視、新增、更新和刪除圖書的路由。

  • 前端:使用HTMX動態載入書籍資料。

項目設定

在設定專案時,我們將從設定permit.io開始。導航到儀表板工作區並建立新專案。我會給我的書店取個名字。

How to Set Up Authorization in a Bookstore Management System with Go, HTMX, and Permit.io

這將創建兩個環境:開發環境和生產環境。

How to Set Up Authorization in a Bookstore Management System with Go, HTMX, and Permit.io

由於我們在本地工作,因此我們將使用開發環境。按一下開發環境中的開啟儀表板,然後按一下建立策略。系統會要求您先建立一個新資源。點選建立資源。為其命名並說明操作。對於這個項目,我將命名我的書籍,操作將是建立、更新、刪除和檢視。

How to Set Up Authorization in a Bookstore Management System with Go, HTMX, and Permit.io

接下來,導覽至策略編輯器部分。預設情況下,您應該會看到已建立的管理員角色。您只需勾選我們新增的檢視操作即可,因為預設無法辨識它。你需要另一個角色。這將供僅具有閱讀權限的使用者使用。

按一下“建立”,然後按一下“角色”並為其指定使用者名稱。建立後,您應該在策略編輯器中看到它,並在剛剛建立的使用者角色中勾選視圖,如下所示:

How to Set Up Authorization in a Bookstore Management System with Go, HTMX, and Permit.io

接下來是註冊將被permit.io授權的使用者。透過側邊欄選單導覽回主選單,您應該仍然有這樣的內容:

How to Set Up Authorization in a Bookstore Management System with Go, HTMX, and Permit.io

點選新增用戶,然後再新增,然後再新增用戶。填寫與資料庫中您的使用者相對應的詳細資訊。

完成後,導覽回您的專案。在書店專案的開發環境中,點擊 3 點圖示。您將看到複製 API 金鑰的選項。複製並將其保存在某處,因為您的專案將需要它。

設定資料庫

建立一個名為 bookstore 的 PostgreSQL 資料庫。您需要設定兩個表:

  • 使用者表: 儲存使用者憑證和角色:
CREATE TABLE users (
  id SERIAL PRIMARY KEY,
  username VARCHAR(255) NOT NULL,
  password_hash VARCHAR(255) NOT NULL,
  role VARCHAR(50) NOT NULL
);

繼續填充此內容,但讓每個使用者分別擁有管理員和使用者角色,並確保它們與 Permit.io 上新增的使用者相符。

  • 書籍表:儲存書籍詳細資料:
CREATE TABLE books (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  title VARCHAR(255) NOT NULL,
  author VARCHAR(255) NOT NULL,
  published_at DATE,
  created_at TIMESTAMPTZ DEFAULT now()
);

您不需要填充此內容,我們將在程式碼中進行此操作。

安裝依賴項

您需要安裝以下相依性:

  • github.com/permitio/permit-golang: 提供在 Go 應用程式中使用 Permit.io 處理基於角色的存取控制 (RBAC) 和權限管理的工具。

  • github.com/google/uuid:這提供了產生和使用通用唯一識別碼 (UUID) 的函數。

  • github.com/gorilla/mux: 幫助實現 HTTP 請求路由器和調度程序,用於在 Web 應用程式中處理路由。

  • github.com/joho/godotenv: 這會從 .env 載入環境變數。文件到應用程式中,從而更輕鬆地管理配置設定。

  • github.com/lib/pq:這是 Go 的 Postgres 驅動程序,用於與 PostgreSQL 資料庫通訊。

  • golang.org/x/crypto: 實作 Go 標準函式庫中未包含的補充加密演算法和函式庫。

要安裝這些依賴項,您需要初始化一個新的 Go 模組。這是 Go 中依賴管理的起點。

執行此指令:

CREATE TABLE users (
  id SERIAL PRIMARY KEY,
  username VARCHAR(255) NOT NULL,
  password_hash VARCHAR(255) NOT NULL,
  role VARCHAR(50) NOT NULL
);

接下來,執行此指令:

CREATE TABLE books (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  title VARCHAR(255) NOT NULL,
  author VARCHAR(255) NOT NULL,
  published_at DATE,
  created_at TIMESTAMPTZ DEFAULT now()
);

這將安裝上面列出的所有依賴項。

設定您的 PDP(策略決策點)容器

要設定 PDP,您需要啟動 docker。完成後,打開終端機並執行以下命令:

go mod init bookstore

之後,您需要使用以下命令運行容器:

go get github.com/google/uuid \
       github.com/gorilla/mux \
       github.com/joho/godotenv \
       github.com/lib/pq \
       github.com/permitio/permit-golang \
       golang.org/x/crypto

取代部分使用您的實際 API 金鑰。現在,讓我們開始建造。

建立應用程式

為了建立應用程序,我們的專案結構如下:

docker pull permitio/pdp-v2:latest

首先,我們將 API 金鑰加入到 .env 檔案中。建立一個,然後建立您的授權 API 金鑰,如下所示:

 docker run -it -p 7766:7000 --env PDP_DEBUG=True --env PDP_API_KEY=<YOUR_API_KEY> permitio/pdp-v2:latest

配置資料庫連接

建立一個名為 config 的資料夾。在其中建立一個名為 config.go 的檔案。新增以下程式碼:

Bookstore                
├── config               
│   └── config.go        
│
├── handlers             
│   └── handlers.go      
│
├── middleware           
│   └── middleware.go    
│
├── models               
│   └── models.go        
│
├── templates            
│   ├── add.html         
│   ├── books.html       
│   ├── index.html       
│   ├── layout.html      
│   ├── login.html       
│   └── update.html      
│
├── main.go              
└── .env

這只是我們設定連接到 PostgreSQL 資料庫的設定。

建立處理程序

接下來,建立一個名為 handlers 的資料夾,並在其中建立一個名為 handlers.go 的檔案。在其中加入以下程式碼:

export PERMIT_API_KEY=”your_api_key”

除了導入套件之外,我們在這裡嘗試做的是建立一個保存資料庫連接和 Permit.io 的結構。我們還提供了一個初始化函數,用於使用本地 PDP 設定 Permit.io。

在 NewHandlers 之後加入以下內容:

package config

import (
  "database/sql"
  "fmt"

  _ "github.com/lib/pq"
)

type Config struct {
  DB       *sql.DB
  Port     string
  DBConfig PostgresConfig
}

type PostgresConfig struct {
  Host     string
  Port     string
  User     string
  Password string
  DBName   string
}

func NewConfig() *Config {
  return &Config{
    Port: "8080",
    DBConfig: PostgresConfig{
      Host:     "localhost",
      Port:     "5432",
      User:     "bookstore_user",
      Password: "your_password",
      DBName:   "bookstore_db",
    },
  }
}

func (c *Config) ConnectDB() error {
  connStr := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable",
    c.DBConfig.Host,
    c.DBConfig.Port,
    c.DBConfig.User,
    c.DBConfig.Password,
    c.DBConfig.DBName,
  )

  db, err := sql.Open("postgres", connStr)
  if err != nil {
    return fmt.Errorf("error opening database: %v", err)
  }

  if err := db.Ping(); err != nil {
    return fmt.Errorf("error connecting to database: %v", err)
  }

  c.DB = db
  return nil
}

LoginHandler 執行下列操作:

  • 處理 GET(顯示登入表單)和 POST(處理登入)。
  • 根據資料庫對使用者進行身份驗證。
  • 為經過驗證的使用者設定會話 cookie。
  • 與 Permit.io 同步使用者資料以進行授權。
  • 根據登入成功/失敗呈現適當的範本。

下一步是新增圖書處理程序來存取圖書。它還將利用 Permit.io 來驗證用戶的角色。在 LoginHandler 之後加入以下程式碼:

package handlers

import (
  "bookstore/middleware"
  "bookstore/models" 
  "context"
  "database/sql"
  "fmt"
  "html/template"
  "net/http"
  "strings"
  "time"

  "github.com/google/uuid"
  "github.com/permitio/permit-golang/pkg/config"
  "github.com/permitio/permit-golang/pkg/enforcement"
  permitModels "github.com/permitio/permit-golang/pkg/models"
  "github.com/permitio/permit-golang/pkg/permit"
)

var tmpl = template.Must(template.ParseGlob("templates/*.html"))

func StringPtr(s string) *string {
  return &s
}

type Handlers struct {
  db           *sql.DB
  permitClient *permit.Client
}

func NewHandlers(db *sql.DB, apiKey string) *Handlers {
  permitConfig := config.NewConfigBuilder(apiKey).
    WithPdpUrl("http://localhost:7766").
    Build()
  permitClient := permit.NewPermit(permitConfig)
  if permitClient == nil {
    panic("Failed to initialize Permit.io client")
  }

  return &Handlers{
    db:           db,
    permitClient: permitClient,
  }
}

BookHandler 執行下列操作:

  • 透過 cookie 檢查使用者驗證。
  • 使用 Permit.io 驗證使用者角色和權限。
  • 如果獲得授權,則從資料庫中取得書籍。
  • 使用取得的資料渲染書籍範本。
  • 適當處理授權失敗。

接下來,您需要一個處理程序來新增書籍。它還將透過 Permit.io 驗證使用者的角色,以確保只有授權使用者才能添加書籍:

CREATE TABLE users (
  id SERIAL PRIMARY KEY,
  username VARCHAR(255) NOT NULL,
  password_hash VARCHAR(255) NOT NULL,
  role VARCHAR(50) NOT NULL
);

AddBookHandler 執行下列操作:

  • 檢查使用者建立圖書的權限。
  • 處理 GET(顯示表單)和 POST(新增書籍)。
  • 驗證輸入資料。
  • 為新書產生 UUID。
  • 處理發布日期的日期解析。
  • 新增成功後重新導向至圖書清單。

您還需要兩個處理程序,一個用於刪除,另一個用於更新。在 AddBookHandler 函數之後新增此程式碼:

CREATE TABLE books (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  title VARCHAR(255) NOT NULL,
  author VARCHAR(255) NOT NULL,
  published_at DATE,
  created_at TIMESTAMPTZ DEFAULT now()
);

DeleteBookHandler 執行以下操作:

  • 驗證使用者刪除權限。
  • 驗證圖書 ID。
  • 執行資料庫刪除。
  • 處理錯誤並適當重定向。

在DeleteBookHandler函數之後,加入以下內容:

go mod init bookstore

UpdateHandler 執行以下操作:

  • 檢查更新權限。
  • 處理 GET(顯示編輯表單)和 POST(更新書籍)。
  • 取得現有圖書資料進行編輯。
  • 驗證並處理更新。
  • 處理日期格式與資料庫更新。

在整個程式碼中,您會注意到授權系統是圍繞 Permit.io 基於角色的存取控制框架構建的,該框架提供了複雜的權限管理。

該系統還可以對使用者操作進行細粒度控制,並允許不同層級的存取權限來查看、建立、更新和刪除資源。應用程式中的每個操作都會經過詳細的權限檢查,確保使用者只能執行其授權的操作。

建立授權中介軟體

現在我們已經完成處理程序了。建立一個名為 middleware 的資料夾,並在其中建立一個名為 middleware.go 的檔案。新增以下程式碼:

go get github.com/google/uuid \
       github.com/gorilla/mux \
       github.com/joho/godotenv \
       github.com/lib/pq \
       github.com/permitio/permit-golang \
       golang.org/x/crypto

此中間件套件有助於提供安全的密碼雜湊和身份驗證,以及用於在書店應用程式中管理圖書的 CRUD 操作。它使用 bcrypt 對密碼進行哈希處理以進行安全存儲,並在登入期間驗證密碼雜湊值。它還可以防止敏感資料的暴露。

LoginUser 函數透過將使用者的輸入與儲存的密碼雜湊進行比較來對使用者進行身份驗證,並在成功登入時檢索完整的使用者設定文件,不包括密碼雜湊以增加安全性。

此外,CRUD 操作可讓您在資料庫中建立、更新、檢索和刪除圖書記錄,並透過存取控制確保只有授權使用者才能修改或刪除他們建立的條目。該軟體包還包括一個 GetUserRole 函數來檢索使用者角色,促進基於角色的存取控制。

創建模型

建立另一個名為 models 的資料夾,並在其中建立一個名為 models.go 的檔案。並加入以下內容:

CREATE TABLE users (
  id SERIAL PRIMARY KEY,
  username VARCHAR(255) NOT NULL,
  password_hash VARCHAR(255) NOT NULL,
  role VARCHAR(50) NOT NULL
);

此套件為書店應用程式定義了多個資料模型,包括 User、Book 和 LoginRequest 結構,以及用於處理資料庫中可為空的 UUID 的自訂 NullUUID 類型。

快完成了。您需要做的下一件事是為您的專案建立模板。您需要建立用於登入和索引的模板,以新增圖書、查看圖書、刪除圖書和更新圖書。

建立 HTML 模板

建立一個名為 templates 的資料夾。這是您的 html 模板所在的位置。
對於登錄,建立一個名為 login.html 的文件,並在其中貼上以下內容:

CREATE TABLE books (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  title VARCHAR(255) NOT NULL,
  author VARCHAR(255) NOT NULL,
  published_at DATE,
  created_at TIMESTAMPTZ DEFAULT now()
);

這個主包充當書店應用程式的入口點。它設定資料庫連線、環境配置和 HTTP 路由來處理使用者登入和圖書管理。

在主函數中,使用 Gorilla Mux 路由器註冊路由。 handlers.NewHandlers 函式使用資料庫和 Permit.io API 金鑰初始化處理程序。它支援使用者身份驗證(/登入)和圖書管理(/books、/add、/delete、/update)等功能。每個路由都會對應到特定的 HTTP 方法,組織不同操作的端點。

最後,伺服器在連接埠 8080 上啟動,偵聽傳入請求並記錄發生的任何錯誤。此設定可確保結構化 API 端點配置和環境變數的安全處理。

測試應用程式

現在這就是一切了!讓我們啟動我們的應用程式來看看。結果。若要啟動伺服器,請執行以下命令:

go mod init bookstore

在瀏覽器中造訪http://localhost:8080/login。

讓我們先測試 standard_user 的權限:

How to Set Up Authorization in a Bookstore Management System with Go, HTMX, and Permit.io

您將看到 standard_user 僅限於查看圖書,無法新增、刪除或更新圖書。

現在讓我們使用 admin_user 登入看看會發生什麼:

How to Set Up Authorization in a Bookstore Management System with Go, HTMX, and Permit.io

您會看到管理員有權執行任何操作!這就是 Permit 的堅固性和易用性!

您可以查看以下資源以了解更多有關 Permit 授權的資訊:

  • 應用程式中的身份驗證和授權。
  • 有效使用者權限和存取委派的最佳實務。
  • 什麼是細粒度授權

結論

在本教程中,我們建立了一個簡單的書店管理應用程序,以使用 Go、HTMX 和 Permit.io 實現基於角色的存取控制。授權是應用程式安全的基本方面,因為它確保用戶只能存取他們被允許的內容。

在您的應用程式中實施有效的存取控制模型(如 RBAC 或 ABAC)不僅可以保護您的應用程序,還可以增強其可擴展性和合規性。

以上是如何使用 Go、HTMX 和 Permit.io 在書店管理系統中設定授權的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn