如何使用 Go、HTMX 和 Permit.io 在书店管理系统中设置授权
授权在构建应用程序时非常重要,因为它决定了用户在进行身份验证后可以访问哪些操作和资源。
在本文中,我们将了解如何使用 Permit.io 实现授权。为了演示它,我们将使用 Golang 和 HTMX 构建一个简单的书店应用程序(我是一个超级粉丝)。
先决条件
要完成本教程,应满足以下先决条件:
- Golang 的安装以及对它的基本了解。
- Permit.io 帐户。
- Docker 已安装。
- 对 HTML、HTTP 和 REST API 的基本了解。
- PostgreSQL(数据库)。
- 熟悉 SQL。
项目范围
- 对于本次演示,我们将保持简单。我们将有两种用户类型:管理员和标准用户。两者都将在 Permit.io 上注册。登录后,数据库将查询 Permit.io 来确定用户的角色并授权他们的操作。
所有用户(包括管理员)都可以阅读书籍。管理员还可以添加、删除和更新图书。标准用户仅限于阅读书籍。
本教程将指导您设置具有基本授权的书店应用程序。我们将实施:
授权逻辑:使用 Permit.io 定义角色(管理员和标准用户)来限制或授予对不同资源的访问权限。
数据库:设置 PostgreSQL 数据库来存储图书和用户数据。
处理程序: 通过访问控制检查实现查看、添加、更新和删除图书的路由。
前端:使用HTMX动态加载图书数据。
项目设置
在设置项目时,我们将从设置permit.io开始。导航到仪表板工作区并创建一个新项目。我会给我的书店起个名字。
这将创建两个环境:开发环境和生产环境。
由于我们在本地工作,因此我们将使用开发环境。单击开发环境中的打开仪表板,然后单击创建策略。系统会要求您首先创建一个新资源。单击创建资源。为其命名并说明操作。对于这个项目,我将命名我的书籍,操作将是创建、更新、删除和查看。
接下来,导航到策略编辑器部分。默认情况下,您应该看到已创建的管理员角色。您只需勾选我们添加的查看操作即可,因为默认情况下无法识别它。你需要另一个角色。这将供仅具有阅读权限的用户使用。
单击“创建”,然后单击“角色”并为其指定用户名。创建后,您应该在策略编辑器中看到它,并在刚刚创建的用户角色中勾选视图,如下所示:
接下来是注册将被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
替换
构建应用程序
为了构建应用程序,我们的项目结构如下:
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 的权限:
您将看到 standard_user 仅限于查看图书,无法添加、删除或更新图书。
现在让我们使用 admin_user 登录看看会发生什么:
您会看到管理员有权执行任何操作!这就是 Permit 的坚固性和易用性!
您可以查看以下资源以了解更多有关 Permit 授权的信息:
- 应用程序中的身份验证和授权。
- 有效用户权限和访问委派的最佳实践。
- 什么是细粒度授权
结论
在本教程中,我们构建了一个简单的书店管理应用程序,以使用 Go、HTMX 和 Permit.io 实现基于角色的访问控制。授权是应用程序安全的基本方面,因为它确保用户只能访问他们被允许的内容。
在您的应用程序中实施有效的访问控制模型(如 RBAC 或 ABAC)不仅可以保护您的应用程序,还可以增强其可扩展性和合规性。
以上是如何使用 Go、HTMX 和 Permit.io 在书店管理系统中设置授权的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

Golang在性能和可扩展性方面优于Python。1)Golang的编译型特性和高效并发模型使其在高并发场景下表现出色。2)Python作为解释型语言,执行速度较慢,但通过工具如Cython可优化性能。

Golang在并发性上优于C ,而C 在原始速度上优于Golang。1)Golang通过goroutine和channel实现高效并发,适合处理大量并发任务。2)C 通过编译器优化和标准库,提供接近硬件的高性能,适合需要极致优化的应用。

goisidealforbeginnersandsubableforforcloudnetworkservicesduetoitssimplicity,效率和concurrencyFeatures.1)installgromtheofficialwebsitealwebsiteandverifywith'.2)

Golang适合快速开发和并发场景,C 适用于需要极致性能和低级控制的场景。1)Golang通过垃圾回收和并发机制提升性能,适合高并发Web服务开发。2)C 通过手动内存管理和编译器优化达到极致性能,适用于嵌入式系统开发。

GoimpactsdevelopmentPositationalityThroughSpeed,效率和模拟性。1)速度:gocompilesquicklyandrunseff,ifealforlargeprojects.2)效率:效率:ITScomprehenSevestAndArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdEcceSteral Depentencies,增强开发的简单性:3)SimpleflovelmentIcties:3)简单性。

Golang和Python各有优势:Golang适合高性能和并发编程,Python适用于数据科学和Web开发。 Golang以其并发模型和高效性能着称,Python则以简洁语法和丰富库生态系统着称。

Golang和C 在性能上的差异主要体现在内存管理、编译优化和运行时效率等方面。1)Golang的垃圾回收机制方便但可能影响性能,2)C 的手动内存管理和编译器优化在递归计算中表现更为高效。

Golang和C 在性能竞赛中的表现各有优势:1)Golang适合高并发和快速开发,2)C 提供更高性能和细粒度控制。选择应基于项目需求和团队技术栈。
