PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Chuyển id người dùng đến trình kích hoạt PostgreSQL

Các tùy chọn bao gồm:

  • Khi bạn mở một kết nối, CREATE TEMPORARY TABLE current_app_user(username text); INSERT INTO current_app_user(username) VALUES ('the_user'); . Sau đó, trong trình kích hoạt của bạn, SELECT username FROM current_app_user để lấy tên người dùng hiện tại, có thể là một truy vấn con.

  • Trong postgresql.conf tạo một mục nhập cho một GUC tùy chỉnh như my_app.username = 'unknown'; . Bất cứ khi nào bạn tạo kết nối, hãy chạy SET my_app.username = 'the_user'; . Sau đó, trong trình kích hoạt, sử dụng current_setting('my_app.username') để lấy giá trị. Một cách hiệu quả, bạn đang lạm dụng máy móc GUC để cung cấp các biến phiên. Đọc tài liệu thích hợp với phiên bản máy chủ của bạn, vì GUC tùy chỉnh đã thay đổi trong 9.2 .

  • Điều chỉnh ứng dụng của bạn để nó có các vai trò cơ sở dữ liệu cho mọi người dùng ứng dụng. SET ROLE cho người dùng đó trước khi thực hiện công việc. Điều này không chỉ cho phép bạn sử dụng current_user tích hợp sẵn hàm giống biến thành SELECT current_user; , nó cũng cho phép bạn thực thi bảo mật trong cơ sở dữ liệu . Xem câu hỏi này. Bạn có thể đăng nhập trực tiếp với tư cách người dùng thay vì sử dụng SET ROLE , nhưng điều đó có xu hướng làm cho việc tổng hợp kết nối trở nên khó khăn.

Trong cả ba trường hợp bạn đang gộp kết nối, bạn phải cẩn thận DISCARD ALL; khi bạn trả về một kết nối với pool. (Mặc dù nó không được ghi lại là làm như vậy, hãy DISCARD ALL thực hiện RESET ROLE ).

Thiết lập chung cho các bản demo:

CREATE TABLE tg_demo(blah text);
INSERT INTO tg_demo(blah) VALUES ('spam'),('eggs');

-- Placeholder; will be replaced by demo functions
CREATE OR REPLACE FUNCTION get_app_user() RETURNS text AS $$
SELECT 'unknown';
$$ LANGUAGE sql;

CREATE OR REPLACE FUNCTION tg_demo_trigger() RETURNS trigger AS $$
BEGIN
    RAISE NOTICE 'Current user is: %',get_app_user();
    RETURN NULL;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER tg_demo_tg
AFTER INSERT OR UPDATE OR DELETE ON tg_demo 
FOR EACH ROW EXECUTE PROCEDURE tg_demo_trigger();

Sử dụng GUC:

  • Trong CUSTOMIZED OPTIONS phần của postgresql.conf , thêm một dòng như myapp.username = 'unknown_user' . Trên các phiên bản PostgreSQL cũ hơn 9.2, bạn cũng phải đặt custom_variable_classes = 'myapp' .
  • Khởi động lại PostgreSQL. Bây giờ bạn sẽ có thể SHOW myapp.username và nhận giá trị unknown_user .

Bây giờ bạn có thể sử dụng SET myapp.username = 'the_user'; khi bạn thiết lập kết nối, hoặc thay thế SET LOCAL myapp.username = 'the_user'; sau BEGIN bắt đầu một giao dịch nếu bạn muốn nó là giao dịch cục bộ, điều này thuận tiện cho các kết nối tổng hợp.

get_app_user định nghĩa hàm:

CREATE OR REPLACE FUNCTION get_app_user() RETURNS text AS $$
    SELECT current_setting('myapp.username');
$$ LANGUAGE sql;

Demo sử dụng SET LOCAL cho tên người dùng hiện tại địa phương giao dịch:

regress=> BEGIN;
BEGIN
regress=> SET LOCAL myapp.username = 'test_user';
SET
regress=> INSERT INTO tg_demo(blah) VALUES ('42');
NOTICE:  Current user is: test_user
INSERT 0 1
regress=> COMMIT;
COMMIT
regress=> SHOW myapp.username;
 myapp.username 
----------------
 unknown_user
(1 row)

Nếu bạn sử dụng SET thay vì SET LOCAL cài đặt sẽ không được hoàn nguyên vào thời gian cam kết / khôi phục, vì vậy nó sẽ liên tục trong suốt phiên. Nó vẫn được đặt lại bằng DISCARD ALL :

regress=> SET myapp.username = 'test';
SET
regress=> SHOW myapp.username;
 myapp.username 
----------------
 test
(1 row)

regress=> DISCARD ALL;
DISCARD ALL
regress=> SHOW myapp.username;
 myapp.username 
----------------
 unknown_user
(1 row)

Ngoài ra, lưu ý rằng bạn không thể sử dụng SET hoặc SET LOCAL với các tham số ràng buộc phía máy chủ. Nếu bạn muốn sử dụng các tham số ràng buộc ("câu lệnh chuẩn bị"), hãy xem xét sử dụng biểu mẫu hàm set_config(...) . Xem các chức năng quản trị hệ thống

Sử dụng bảng tạm thời

Cách tiếp cận này yêu cầu sử dụng một trình kích hoạt (hoặc chức năng trợ giúp được gọi bởi trình kích hoạt, tốt hơn là) cố gắng đọc một giá trị từ một bảng tạm thời mà mọi phiên nên có. Nếu không tìm thấy bảng tạm thời, giá trị mặc định sẽ được cung cấp. Điều này có thể hơi chậm . Kiểm tra cẩn thận.

get_app_user() định nghĩa:

CREATE OR REPLACE FUNCTION get_app_user() RETURNS text AS $$
DECLARE
    cur_user text;
BEGIN
    BEGIN
        cur_user := (SELECT username FROM current_app_user);
    EXCEPTION WHEN undefined_table THEN
        cur_user := 'unknown_user';
    END;
    RETURN cur_user;
END;
$$ LANGUAGE plpgsql VOLATILE;

Demo:

regress=> CREATE TEMPORARY TABLE current_app_user(username text);
CREATE TABLE
regress=> INSERT INTO current_app_user(username) VALUES ('testuser');
INSERT 0 1
regress=> INSERT INTO tg_demo(blah) VALUES ('42');
NOTICE:  Current user is: testuser
INSERT 0 1
regress=> DISCARD ALL;
DISCARD ALL
regress=> INSERT INTO tg_demo(blah) VALUES ('42');
NOTICE:  Current user is: unknown_user
INSERT 0 1

Các biến phiên bảo mật

Ngoài ra còn có một đề xuất để thêm "các biến phiên bảo mật" vào PostgreSQL. Đây là một chút giống như các biến gói. Kể từ PostgreSQL 12, tính năng này vẫn chưa được bao gồm, nhưng hãy để ý và lên tiếng về danh sách tin tặc nếu đây là thứ bạn cần.

Nâng cao:tiện ích mở rộng của riêng bạn với vùng bộ nhớ dùng chung

Đối với các mục đích sử dụng nâng cao, bạn thậm chí có thể có phần mở rộng C của riêng mình đăng ký một vùng bộ nhớ được chia sẻ và giao tiếp giữa các phần phụ trợ bằng cách sử dụng các lệnh gọi hàm C đọc / ghi các giá trị trong một phân đoạn DSA. Xem các ví dụ lập trình PostgreSQL để biết chi tiết. Bạn sẽ cần kiến ​​thức C, thời gian và sự kiên nhẫn.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Các tính năng ẩn của PostgreSQL

  2. Lưu trữ PostgreSQL được quản lý hoàn toàn trên AWS và Azure ra mắt kịp thời cho những lần di chuyển kế thừa

  3. Làm cách nào để xử lý việc mở / đóng kết nối Db trong ứng dụng Go?

  4. Hàm MAX () trong PostgreSQL

  5. Tổng quan về khả năng JSON trong PostgreSQL