承認は、ユーザーが認証後にアクセスできるアクションとリソースを決定するため、アプリケーションを構築する際に重要です。
この記事では、permit.io を使用して認可を実装する方法を見ていきます。それを実証するために、Golang と HTMX を使用してシンプルな書店アプリを構築します (私は大ファンです)。
このチュートリアルを進めるには、次の前提条件を満たす必要があります:
すべてのユーザー (管理者を含む) が書籍を読むことができます。管理者は書籍を追加、削除、更新することもできます。標準ユーザーは書籍の閲覧に限定されています。
このチュートリアルでは、基本的な認証を使用して書店アプリケーションをセットアップする方法を説明します。以下を実装します:
認可ロジック: Permit.io を使用してロール (管理者および標準ユーザー) を定義し、さまざまなリソースへのアクセスを制限または許可します。
データベース: 書籍とユーザーのデータを保存するために PostgreSQL データベースをセットアップします。
ハンドラー: アクセス制御チェックを使用して書籍を表示、追加、更新、削除するためのルートを実装します。
フロントエンド: HTMX を使用して書籍データを動的に読み込みます。
プロジェクトのセットアップでは、まずpermit.ioをセットアップします。ダッシュボード ワークスペースに移動し、新しいプロジェクトを作成します。書店の名前を付けておきます。
これにより、開発環境と運用環境という 2 つの環境が作成されます。
ローカルで作業しているため、開発環境を使用します。 「開発環境でダッシュボードを開く」をクリックし、「ポリシーの作成」をクリックします。最初に新しいリソースを作成するように求められます。 「リソースの作成」をクリックします。名前を付けてアクションを記述します。このプロジェクトでは、マイン ブックに名前を付け、アクションは作成、更新、削除、表示となります。
次に、ポリシーエディタセクションに移動します。デフォルトでは、管理者ロールがすでに作成されていることが表示されます。デフォルトでは認識されないため、追加した表示アクションにチェックを入れるだけです。別の役割が必要です。これは、読み取り権限のみを持つユーザーが対象となります。
[作成]、[役割] の順にクリックし、ユーザーの名前を付けます。作成したら、ポリシー エディターにそれが表示され、次のように作成したばかりのユーザー ロールのビューにチェックを入れる必要があります。
次に、permit.io によって許可されるユーザーを登録します。サイドバー メニューからホーム メニューに戻ると、次のようなものがまだ表示されているはずです。
「ユーザーを追加」をクリックしてから「追加」をクリックし、さらに「ユーザーを追加」をクリックします。データベース内のユーザーに対応する詳細を入力します。
それが完了したら、プロジェクトに戻ります。書店プロジェクトの開発環境で、3 つの点線のアイコンをクリックします。 API キーをコピーするオプションが表示されます。プロジェクトで必要になるため、コピーしてどこかに保存します。
bookstore という PostgreSQL データベースを作成します。 2 つのテーブルを設定する必要があります:
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: Web アプリケーションでルートを処理するための HTTP リクエスト ルーターとディスパッチャーの実装に役立ちます。
github.com/joho/godotenv: これにより、.env から環境変数がロードされます。ファイルをアプリケーションに追加できるため、構成設定の管理が容易になります。
github.com/lib/pq: これは、PostgreSQL データベースと通信するための Go の Postgres ドライバーです。
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 をセットアップするには、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
まず、.env ファイル内に API キーを追加しましょう。作成してから、次のように許可 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 をセットアップする初期化関数も提供しています。
NewHandler がこれを追加した直後:
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 は次の処理を行います:
次のステップは、書籍にアクセスするための書籍ハンドラーを追加することです。また、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 は次のことを行います:
次に、書籍を追加するハンドラーが必要です。また、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 は次の処理を行います:
さらに 2 つのハンドラーが必要です。1 つは削除用、もう 1 つは更新用です。このコードを 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 は次のことを行います:
DeleteBookHandler 関数の直後に、次の行を追加します。
go mod init bookstore
UpdateHandler は次の処理を行います:
コード全体を通して、洗練された権限管理を提供する 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 構造を含む書店アプリケーション用のいくつかのデータ モデルと、データベース内の null 許容 UUID を処理するためのカスタム NullUUID タイプを定義します。
ほぼ完了しました。次に行う必要があるのは、プロジェクトのテンプレートを作成することです。書籍の追加、書籍の表示、書籍の削除、書籍の更新を行うには、ログインとインデックスのテンプレートを作成する必要があります。
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 ルートを設定します。
main関数では、Gorilla Muxルーターを使用してルートを登録します。 handlers.NewHandlers 関数は、データベースと Permit.io API キーを使用してハンドラーを初期化します。ユーザー認証 (/login) や書籍管理 (/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 中国語 Web サイトの他の関連記事を参照してください。