Trang chủHướng dẫnHướng dẫn quản lý Role và phân quyền trong PostgreSQL trên Ubuntu 22.04

Hướng dẫn quản lý Role và phân quyền trong PostgreSQL trên Ubuntu 22.04

CyStack blog 11 phút để đọc
CyStack blog12/09/2025
Locker Avatar

Chris Pham

Technical Writer

Locker logo social
Reading Time: 11 minutes

PostgreSQL, hay Postgres, là một hệ thống quản lý cơ sở dữ liệu quan hệ mã nguồn mở. Giống như các cơ sở dữ liệu quan hệ khác, PostgreSQL lưu trữ dữ liệu trong các bảng được tạo thành từ các hàng và các cột.

phân quyền trong PostgreSQL

Người dùng có thể định nghĩa, thao tác, kiểm soát và truy vấn dữ liệu bằng ngôn ngữ truy vấn có cấu trúc, thường được gọi là SQL. PostgreSQL là một công cụ mạnh mẽ có thể được sử dụng để quản lý dữ liệu ứng dụng và web trên một Máy chủ riêng ảo.

Hướng dẫn này sẽ trình bày cách quản lý Role và phân quyền trong PostgreSQL một cách hợp lý. Điều này sẽ cho phép bạn cung cấp cho các ứng dụng của mình các đặc quyền cần thiết mà không ảnh hưởng đến các cơ sở dữ liệu riêng biệt.

Điều kiện tiên quyết

Để làm theo hướng dẫn này, bạn cần:

  • Một máy chủ Ubuntu 22.04 đã được cấu hình bằng cách làm theo hướng dẫn Initial Server Setup for Ubuntu 22.04. Sau khi hoàn thành, máy chủ của bạn nên có một người dùng non-root với các đặc quyền sudo và một tường lửa cơ bản.
  • Hoàn thành Bước 1 của hướng dẫn How To Install and Use PostgreSQL on Ubuntu 22.04 để cài đặt Postgres trên máy chủ của bạn.

Sau khi môi trường của bạn đã sẵn sàng và Postgres đang chạy trên máy chủ, bạn có thể bắt đầu tìm hiểu về cách Postgres xử lý các quyền hạn.

Xem các Role và quyền trong PostgreSQL

Postgres quản lý các quyền thông qua khái niệm roles (vai trò). Các roles khác với các quyền kiểu Unix truyền thống ở chỗ không có sự phân biệt giữa người dùng và nhóm. Roles có thể được điều chỉnh để giống cả hai quy ước này, nhưng chúng cũng linh hoạt hơn. Khi cài đặt, Postgres được thiết lập để sử dụng peer authentication (xác thực ngang hàng), có nghĩa là nó liên kết các roles của Postgres với một tài khoản hệ thống Unix/Linux tương ứng. Nếu một role tồn tại trong Postgres, một tên người dùng Unix/Linux có cùng tên có thể đăng nhập với tư cách là role đó.

Quy trình cài đặt đã tạo một tài khoản người dùng có tên postgres được liên kết với role mặc định của Postgres. Để sử dụng Postgres, bạn có thể đăng nhập vào tài khoản đó.

Đầu tiên, đảm bảo máy chủ của bạn đang chạy bằng cách sử dụng lệnh systemctl start:

sudo systemctl start postgresql.service

Sau đó, bạn có thể chuyển sang tài khoản postgres bằng cách gõ:

sudo -i -u postgres

Bây giờ bạn có thể truy cập ngay dấu nhắc PostgreSQL bằng cách gõ:

psql

Để liệt kê các roles trong thể hiện Postgres của bạn, hãy gõ lệnh sau:

\\du
Output
                                   List of roles
 Role name |                         Attributes                         | Member of
-----------+------------------------------------------------------------+-----------
 postgres  | Superuser, Create role, Create DB, Replication, Bypass RLS | {}

Hiện tại, chỉ có một role mặc định với nhiều đặc quyền mạnh mẽ.

Tạo Role trong PostgreSQL

Có một số cách khác nhau để tạo roles cho Postgres. Có thể tạo roles từ bên trong Postgres, hoặc từ dòng lệnh.

Tạo Role từ bên trong PostgreSQL

Một cách để tạo một role mới là từ giao diện dấu nhắc Postgres (Postgres prompt). Sau đây là cú pháp để tạo một role mới trong giao diện này:

CREATE ROLE new_role_name;

Để minh họa, hãy tạo một role mới có tên demo_role:

CREATE ROLE demo_role;

Kiểm tra lại những người dùng đã được định nghĩa:

\\du
Output
                                   List of roles
 Role name |                         Attributes                         | Member of
-----------+------------------------------------------------------------+-----------
 demo_role | Cannot login                                               | {}
 postgres  | Superuser, Create role, Create DB, Replication, Bypass RLS | {}

Kết quả của bạn sẽ hiển thị hai người dùng.

Tạo Role từ dòng lệnh

Một phương pháp thay thế để tạo roles là sử dụng lệnh createuser từ dòng lệnh.

Đầu tiên, thoát khỏi dấu nhắc lệnh PostgreSQL trong giây lát bằng cách gõ:

\\q

Sau đó, đăng nhập vào tài khoản postgres:

sudo -i -u postgres

Bạn có thể tạo các roles mới từ dòng lệnh với lệnh createuser. Sử dụng cờ --interactive sẽ nhắc bạn nhập tên của role mới và cũng hỏi xem nó có nên có đặc quyền superuser hay không.

Đăng nhập với tư cách là tài khoản postgres, bạn có thể tạo một người dùng mới bằng cách gõ:

createuser --interactive

Tập lệnh sẽ nhắc bạn với một số lựa chọn và, dựa trên câu trả lời của bạn, thực thi các lệnh Postgres chính xác theo yêu cầu của bạn:

Output
Enter name of role to add:test_user
Shall the new role be a superuser? (y/n)n
Shall the new role be allowed to create databases? (y/n)n
Shall the new role be allowed to create more new roles? (y/n)n

Bằng cách trả lời n cho tất cả các lời nhắc này, bạn sẽ tạo một người dùng tương tự như người dùng trước.

Đăng nhập lại vào dấu nhắc Postgres psql của bạn:

psql

Sau đó, thực thi lệnh \\du để tiết lộ sự khác biệt giữa hai roles mới. Lệnh này bắt đầu bằng \\ vì nó là một meta-command cụ thể của psql được chính psql xử lý chứ không phải bởi PostgreSQL:

\\du

Output
                                   List of roles
 Role name |                         Attributes                         | Member of
-----------+------------------------------------------------------------+-----------
 demo_role | Cannot login                                               | {}
 postgres  | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
 test_user |                                                            | {}

Lưu ý rằng người dùng được tạo từ dòng lệnh không có thuộc tính Cannot login được liệt kê.

Xóa Role trong PostgreSQL

Bạn có thể xóa một role bằng cách sử dụng cú pháp sau:

DROP ROLE role_name;

Để minh họa, hãy xóa role demo_role bằng cách gõ:

DROP ROLE demo_role;

Nếu bạn thực hiện lệnh trên một người dùng không tồn tại, bạn sẽ nhận được một thông báo lỗi:

Output
ERROR:  role "demo_role" does not exist

Để tránh tình huống này và làm cho lệnh xóa một người dùng nếu nó có mặt, và im lặng không làm gì nếu người dùng không tồn tại, hãy sử dụng cú pháp sau:

DROP ROLE IF EXISTS role_name;

Với tùy chọn này được chỉ định, lệnh sẽ hoàn thành thành công bất kể tính hợp lệ của role. Cố gắng xóa demo_role bằng các lệnh trên sẽ dẫn đến kết quả này:

DROP ROLE IF EXISTS demo_role;

Output
NOTICE:  role "demo_role" does not exist, skipping
DROP ROLE

Role hiện đã bị xóa.

Xác định các đặc quyền khi tạo Role

Bây giờ, bạn đã sẵn sàng để tạo lại demo_role với các quyền đã được thay đổi. Bạn có thể làm điều này bằng cách chỉ định các quyền bạn muốn sau mệnh đề tạo chính như thế này:

CREATE ROLE role_name WITH assigned_permissions;

Để xem danh sách đầy đủ các tùy chọn, gõ:

\\h CREATE ROLE
Output
Command:     CREATE ROLE
Description: define a new database role
Syntax:
CREATE ROLE name [ [ WITH ] option [ ... ] ]

where option can be:

      SUPERUSER | NOSUPERUSER
    | CREATEDB | NOCREATEDB
    | CREATEROLE | NOCREATEROLE
    | INHERIT | NOINHERIT
    | LOGIN | NOLOGIN
    | REPLICATION | NOREPLICATION
    | BYPASSRLS | NOBYPASSRLS
    | CONNECTION LIMIT connlimit
    | [ ENCRYPTED ] PASSWORD 'password' | PASSWORD NULL
    | VALID UNTIL 'timestamp'
    | IN ROLE role_name [, ...]
    | IN GROUP role_name [, ...]
    | ROLE role_name [, ...]
    | ADMIN role_name [, ...]
    | USER role_name [, ...]
    | SYSID uid

URL: <https://www.postgresql.org/docs/14/sql-createrole.html>

Bạn có thể cấp cho người dùng demo_role khả năng đăng nhập bằng cách gõ:

CREATE ROLE demo_role WITH LOGIN;

Kiểm tra các thuộc tính với lệnh \\du, hai người dùng hiện có các đặc quyền giống hệt nhau:

Output
                                   List of roles
 Role name |                         Attributes                         | Member of
-----------+------------------------------------------------------------+-----------
 demo_role |                                                            | {}
 postgres  | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
 test_user |                                                            | {}

Bạn có thể đạt được trạng thái này mà không cần chỉ định thuộc tính LOGIN với mỗi lần tạo role. Bằng cách sử dụng lệnh CREATE USER sau, nó tự động cấp cho role đặc quyền đăng nhập:

CREATE USER role_name;

Role được tạo với đặc quyền được cấp tự động.

Thay đổi đặc quyền của Role trong PostgreSQL

Để thay đổi các thuộc tính của một role đã được tạo, hãy sử dụng lệnh ALTER ROLE. Cú pháp cho lệnh này là:

ALTER ROLE role_name WITH attribute_options;

Lệnh này cho phép bạn xác định các thay đổi đặc quyền mà không cần phải xóa và tạo lại người dùng như đã minh họa trước đó. Ví dụ, bạn có thể thay đổi demo_role trở lại trạng thái Cannot login trước đó của nó bằng cách thực hiện lệnh này:

ALTER ROLE demo_role WITH NOLOGIN;

Bạn có thể xác nhận thay đổi bằng lệnh \\du:

\\du

Output
                                   List of roles
 Role name |                         Attributes                         | Member of
-----------+------------------------------------------------------------+-----------
 demo_role | Cannot login                                               | {}
 postgres  | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
 test_user |                                                            | {}

Để thay đổi nó trở lại một role có quyền truy cập đăng nhập, sử dụng lệnh sau:

 ALTER ROLE demo_role WITH LOGIN;

Bây giờ role đã được khôi phục.

Đăng nhập với tư cách một người dùng khác trong PostgreSQL

Theo mặc định, người dùng chỉ được phép đăng nhập cục bộ nếu tên người dùng hệ thống khớp với tên người dùng PostgreSQL. Bạn có thể thay đổi điều này bằng cách thay đổi loại đăng nhập, hoặc bằng cách chỉ định rằng PostgreSQL nên sử dụng giao diện mạng loopback. Điều này thay đổi loại kết nối thành từ xa (remote) mặc dù nó thực sự là một kết nối cục bộ.

Đầu tiên, tạo một mật khẩu cho người dùng bạn muốn kết nối, để nó có thể xác thực. Bạn có thể thử điều này với test_user mà bạn đã tạo trước đó bằng cách đặt cho nó một mật khẩu:

\\password test_user

Bạn sẽ được nhắc nhập và xác nhận một mật khẩu. Bây giờ, thoát khỏi giao diện PostgreSQL và quay lại người dùng bình thường của bạn với lệnh này:

\\q

PostgreSQL giả định rằng khi bạn đăng nhập, bạn sẽ sử dụng một tên người dùng khớp với tên người dùng hệ điều hành của bạn, và bạn sẽ kết nối với một cơ sở dữ liệu có cùng tên.

Để chỉ định rõ ràng các tùy chọn bạn muốn sử dụng, hãy sử dụng cú pháp sau với các tham số của bạn:

psql -U user_name -d database_name -h 127.0.0.1 -W

Đây là một phân tích ngắn gọn về từng mục trong lệnh:

  • user_name nên được thay thế bằng tên người dùng bạn muốn kết nối.
  • database_name nên là tên của một cơ sở dữ liệu hiện có mà bạn có quyền truy cập.
  • Phần h 127.0.0.1 là phần chỉ định rằng bạn sẽ kết nối với máy cục bộ, nhưng thông qua một giao diện mạng, cho phép bạn xác thực ngay cả khi tên người dùng hệ thống của bạn không khớp.
  • Cờ W nói với PostgreSQL rằng bạn sẽ nhập một mật khẩu.

Để đăng nhập với test_user của bạn, hãy thực hiện lệnh sau:

sudo psql -U test_user -d postgres -h 127.0.0.1 -W

Bạn sẽ cần nhập một mật khẩu sau lệnh này.

Trong ví dụ này, bạn sử dụng cơ sở dữ liệu postgres. Đây là cơ sở dữ liệu mặc định được thiết lập trong quá trình cài đặt. Nếu bạn cố gắng thực hiện một số hành động trong phiên này, bạn sẽ thấy rằng bạn không có khả năng làm nhiều việc. Điều này là do test_user chưa được cấp các đặc quyền quản trị.

Thoát phiên hiện tại:

\\q

Sau đó, quay lại phiên quản trị postgres:

sudo u - postgres psql

Tiếp theo, bạn sẽ cấp các quyền.

Cấp quyền trong PostgreSQL

Khi một cơ sở dữ liệu hoặc một bảng được tạo, thường chỉ có role đã tạo ra nó, không bao gồm các roles có trạng thái superuser, có quyền sửa đổi nó. Hành vi này có thể được thay đổi bằng cách cấp quyền cho các roles khác. Bạn có thể cấp quyền bằng cách sử dụng lệnh GRANT với cú pháp chung này:

GRANT permission_type ON table_name TO role_name;

Bạn có thể tạo một bảng để thực hành các khái niệm này với các lệnh sau:

CREATE TABLE demo (
name varchar(25),
id serial,
start_date date);

Để xem bảng bạn đã tạo, nhập lệnh này:

\\d
Output
             List of relations
 Schema |    Name     |   Type   |  Owner
--------+-------------+----------+----------
 public | demo        | table    | postgres
 public | demo_id_seq | sequence | postgres
(2 rows)

Lưu ý rằng có một loại bảng và một loại chuỗi. Chuỗi được tạo cho bạn khi bạn sử dụng lệnh id serial trong quá trình tạo bảng của bạn. Điều này tạo ra một số nguyên tự động tăng dần.

Bây giờ bạn có thể cấp một số đặc quyền cho bảng demo mới cho demo_role. Để làm như vậy, hãy cấp cho người dùng demo_role các đặc quyền UPDATE với lệnh sau:

GRANT UPDATE ON demo TO demo_role;

Bạn có thể cấp đầy đủ quyền cho một người dùng bằng cách thay thế loại quyền bằng từ ALL. Cấp quyền này cho test_user với lệnh này:

GRANT ALL ON demo TO test_user;

Nếu bạn muốn chỉ định quyền cho mọi người dùng trên hệ thống, bạn có thể sử dụng PUBLIC thay vì một người dùng cụ thể:

GRANT INSERT ON demo TO PUBLIC;

Để xem bảng cấp quyền, sử dụng lệnh sau:

\\z
Output
                                      Access privileges
 Schema |    Name     |   Type   |     Access privileges      | Column privileges | Policies
--------+-------------+----------+----------------------------+-------------------+----------
 public | demo        | table    | postgres=arwdDxt/postgres +|                   |
        |             |          | demo_role=w/postgres      +|                   |
        |             |          | test_user=arwdDxt/postgres+|                   |
        |             |          | =a/postgres                |                   |
 public | demo_id_seq | sequence |                            |                   |
(2 rows)

Điều này cho thấy tất cả các quyền đã được cấp.

Xóa quyền trong PostgreSQL

Bạn có thể xóa quyền bằng cách sử dụng lệnh REVOKE. Lệnh REVOKE sử dụng gần như cùng cú pháp với GRANT:

REVOKE permission_type ON table_name FROM user_name;

Bạn cũng có thể sử dụng các từ viết tắt tương tự, ALLPUBLIC, trong lệnh:

REVOKE INSERT ON demo FROM PUBLIC;

Các quyền bạn đã đặt trước đó bây giờ đã bị thu hồi.

Sử dụng Group Roles trong PostgreSQL

Roles đủ linh hoạt để cho phép nhóm các roles khác để cho phép kiểm soát quyền trên diện rộng. Ví dụ, bạn có thể tạo một role mới có tên temporary_users và sau đó thêm demo_roletest_user vào nhóm đó.

Đầu tiên tạo role mới sẽ được sử dụng làm một nhóm:

CREATE ROLE temporary_users;

Sau đó gán người dùng vào nhóm temporary_users mới được tạo:

GRANT temporary_users TO demo_role;

GRANT temporary_users TO test_user;

Bây giờ hai người dùng này có thể có quyền của họ được quản lý bằng cách thao tác với group role temporary_users thay vì quản lý từng thành viên riêng lẻ.

Bạn có thể xem thông tin thành viên role bằng cách gõ:

\\du

Output
                                          List of roles
    Role name    |                         Attributes                         |     Member of
-----------------+------------------------------------------------------------+-------------------
 demo_role       |                                                            | {temporary_users}
 postgres        | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
 temporary_users | Cannot login                                               | {}
 test_user       |                                                            | {temporary_users}

Bất kỳ thành viên nào của một group role đều có thể hành động với tư cách là group role mà họ là thành viên bằng cách sử dụng lệnh SET ROLE. Vì người dùng postgres mà bạn đang đăng nhập hiện có các đặc quyền superuser, bạn có thể sử dụng lệnh SET ROLE ngay cả khi nó không phải là thành viên của nhóm temporary_users:

SET ROLE temporary_users;

Bây giờ, bất kỳ bảng nào được tạo đều thuộc sở hữu của role temporary_users:

CREATE TABLE hello (
name varchar(25),
id serial,
start_date date);

Bây giờ, kiểm tra quyền sở hữu bảng bằng cách thực hiện lệnh này:

\\d

Output
                 List of relations
 Schema |     Name     |   Type   |      Owner
--------+--------------+----------+-----------------
 public | demo         | table    | postgres
 public | demo_id_seq  | sequence | postgres
 public | hello        | table    | temporary_users
 public | hello_id_seq | sequence | temporary_users
(4 rows)

Bảng mới, và chuỗi liên quan đến kiểu dữ liệu serial, thuộc sở hữu của role temporary_users.

Để trở lại các quyền role ban đầu, nhập lệnh sau:

RESET ROLE;

Nếu bạn cấp cho người dùng thuộc tính INHERIT với lệnh ALTER ROLE, người dùng đó sẽ tự động có tất cả các đặc quyền của các roles mà họ thuộc về mà không cần sử dụng lệnh SET ROLE:

ALTER ROLE test_user INHERIT;

Bây giờ test_user sẽ có mọi quyền của các roles mà nó là thành viên. Bạn có thể xóa một group role, hoặc bất kỳ role nào, với lệnh DROP ROLE. Bạn có thể kiểm tra điều này với nhóm temporary_users bằng cách gõ lệnh sau:

DROP ROLE temporary_users;

Output
ERROR:  role "temporary_users" cannot be dropped because some objects depend on it
DETAIL:  owner of sequence hello_id_seq
owner of table hello

Điều này xuất ra một lỗi vì bảng hello thuộc sở hữu của temporary_users. Bạn có thể giải quyết vấn đề này bằng cách chuyển quyền sở hữu cho một role khác:

ALTER TABLE hello OWNER TO demo_role;

Bạn có thể kiểm tra xem temporary_users không còn sở hữu bất kỳ bảng nào nữa với lệnh sau:

\\d

Output
              List of relations
 Schema |     Name     |   Type   |   Owner
--------+--------------+----------+-----------
 public | demo         | table    | postgres
 public | demo_id_seq  | sequence | postgres
 public | hello        | table    | demo_role
 public | hello_id_seq | sequence | demo_role
(4 rows)

Bây giờ bạn có thể xóa role temporary_users thành công bằng cách thực hiện lệnh này:

DROP ROLE temporary_users;

Điều này sẽ hủy bỏ role temporary_users. Các thành viên cũ của temporary_users không bị xóa.

Kết luận

Bây giờ bạn đã có các kỹ năng cơ bản cần thiết để quản lý các quyền cơ sở dữ liệu PostgreSQL của mình. Điều quan trọng là phải biết cách quản lý quyền để các ứng dụng của bạn có thể truy cập các cơ sở dữ liệu mà chúng cần, trong khi không làm gián đoạn dữ liệu được sử dụng bởi các ứng dụng khác.

0 Bình luận

Đăng nhập để thảo luận

Chuyên mục Hướng dẫn

Tổng hợp các bài viết hướng dẫn, nghiên cứu và phân tích chi tiết về kỹ thuật, các xu hướng công nghệ mới nhất dành cho lập trình viên.

Đăng ký nhận bản tin của chúng tôi

Hãy trở thành người nhận được các nội dung hữu ích của CyStack sớm nhất

Xem chính sách của chúng tôi Chính sách bảo mật.

Đăng ký nhận Newsletter

Nhận các nội dung hữu ích mới nhất