Khi ứng dụng Oracle APEX dùng authentication đơn giản như APEX Accounts,
luồng đăng xuất thường không quá phức tạp. User bấm Logout, session APEX bị hủy,
sau đó ứng dụng quay về login page hoặc home page.
Nhưng khi ứng dụng dùng Social Sign-In, OpenID Connect, SAML hoặc một identity provider bên ngoài,
logout không chỉ là hủy session trong APEX. Ứng dụng còn cần điều hướng qua identity provider,
thực hiện logout phía provider, rồi quay lại một URL công khai của ứng dụng.
Vấn đề bắt đầu xuất hiện khi ứng dụng được triển khai trên nhiều môi trường:
DEV có URL riêng, TEST có URL riêng, PROD có URL riêng. Nếu Post-Logout URL bị hard-code trong Authentication Scheme,
mỗi lần deploy sang môi trường khác developer lại phải nhớ chỉnh tay URL.
Đây là một điểm nhỏ nhưng rất dễ gây lỗi trong thực tế. Bài viết này trình bày một pattern đơn giản
để quản lý Post-Logout URL động trong Oracle APEX bằng Application Setting và Application Item.
Post-Logout URL là gì?
Post-Logout URL là URL mà hệ thống sẽ điều hướng đến sau khi quá trình logout hoàn tất.
Với các authentication scheme liên quan đến SSO hoặc Social Sign-In,
URL này thường được dùng để đưa user về một public page của ứng dụng sau khi identity provider xử lý logout.
Ví dụ, bạn có thể muốn user sau khi logout quay về:
https://dokhala.com/logout-complete
Hoặc một page công khai trong APEX:
https://dokhala.com/ords/r/dokhala/dokhala/logout-complete
Nếu chỉ có một môi trường thì cấu hình tĩnh có thể đủ.
Nhưng với nhiều môi trường, URL này cần thay đổi theo từng instance.
Vấn đề khi hard-code Post-Logout URL
Giả sử ứng dụng có ba môi trường:
https://dev.example.com/ords/r/app/home
https://test.example.com/ords/r/app/home
https://app.example.com/ords/r/app/home
Nếu Authentication Scheme đang hard-code Post-Logout URL là URL của DEV,
khi export app từ DEV rồi import sang TEST hoặc PROD, rất có thể logout vẫn quay về DEV.
Lỗi này không phải lỗi code lớn, nhưng có thể gây trải nghiệm rất xấu:
- User logout khỏi PROD nhưng bị redirect về DEV.
- Identity provider báo lỗi vì redirect URL không khớp.
- Logout xong lại bị login tự động ngay lập tức.
- Developer phải chỉnh tay sau mỗi lần deploy.
- CI/CD pipeline không kiểm soát được cấu hình môi trường.
Vì vậy, Post-Logout URL nên được tách thành cấu hình theo môi trường,
không nên để cố định trong app export nếu ứng dụng có nhiều instance.
Lược đồ giải pháp
Dynamic Post-Logout URL trong Oracle APEX
Application Setting
Lưu URL theo từng môi trường DEV, TEST, PROD.
→
After Authentication
Khi user đăng nhập, copy setting vào session state.
→
Application Item
Giữ Post-Logout URL hiện hành trong session.
→
Logout Redirect
Authentication Scheme dùng item này làm Post-Logout URL.
Mục tiêu là đưa URL phụ thuộc môi trường ra khỏi cấu hình hard-code,
giúp deploy ứng dụng an toàn hơn và giảm thao tác chỉnh tay sau mỗi lần import.
Ý tưởng chính
Pattern gồm bốn phần:
- Tạo một Application Setting để lưu Post-Logout URL theo môi trường.
- Tạo một Application Item để chứa URL trong session state.
- Tạo After Authentication Process để copy giá trị setting vào item.
- Cấu hình Post-Logout URL trong Authentication Scheme dùng giá trị của item.
Như vậy, mỗi môi trường chỉ cần giữ giá trị setting riêng.
Khi app được export/import, bạn không cần sửa trực tiếp Authentication Scheme mỗi lần.
Bước 1: Tạo Application Setting
Vào:
Shared Components
→ Application Logic
→ Application Settings
Tạo setting mới:
Name:
POST_LOGOUT_URL
Value:
https://dev.example.com/ords/r/my_workspace/my_app/logout-complete
Điểm quan trọng: bật tùy chọn giữ giá trị khi nâng cấp/import nếu môi trường của bạn hỗ trợ.
Mục tiêu là để mỗi instance giữ URL riêng của nó.
Ví dụ:
- DEV giữ URL DEV.
- TEST giữ URL TEST.
- PROD giữ URL PROD.
Khi deploy app từ DEV sang PROD, giá trị PROD không bị ghi đè nhầm bởi giá trị DEV.
Bước 2: Tạo Application Item
Vào:
Shared Components
→ Application Items
Tạo Application Item:
Name:
AI_POST_LOGOUT_URL
Item này dùng để giữ Post-Logout URL trong session state sau khi user đăng nhập.
Tại sao cần Application Item?
Vì Authentication Scheme cần một giá trị có thể tham chiếu trong runtime.
Application Setting là nơi lưu cấu hình bền vững theo môi trường,
còn Application Item là nơi đưa giá trị đó vào session để dùng trong app.
Bước 3: Tạo After Authentication Application Process
Vào:
Shared Components
→ Application Processes
Tạo process mới:
Name:
SET_POST_LOGOUT_URL
Point:
After Authentication
PL/SQL Code:
begin
apex_session_state.set_value(
p_item => 'AI_POST_LOGOUT_URL',
p_value => apex_app_setting.get_value('POST_LOGOUT_URL')
);
end;
Process này sẽ chạy sau khi user đăng nhập thành công.
Nó lấy giá trị từ Application Setting POST_LOGOUT_URL
rồi ghi vào Application Item AI_POST_LOGOUT_URL.
Bước 4: Cấu hình Post-Logout URL trong Authentication Scheme
Vào:
Shared Components
→ Authentication Schemes
→ Chọn scheme đang dùng
→ Post-Logout URL
Chọn kiểu redirect phù hợp, sau đó đặt URL là:
&AI_POST_LOGOUT_URL.
Khi user logout, APEX sẽ dùng giá trị trong application item để xác định URL cần redirect.
Nhờ vậy, Authentication Scheme không cần hard-code URL DEV, TEST hay PROD.
URL thực tế đến từ Application Setting của từng môi trường.
Ví dụ theo môi trường
DEV:
POST_LOGOUT_URL =
https://dev.dokhala.com/logout-complete
TEST:
POST_LOGOUT_URL =
https://test.dokhala.com/logout-complete
PROD:
POST_LOGOUT_URL =
https://dokhala.com/logout-complete
Ứng dụng dùng cùng một Authentication Scheme, cùng một Application Item,
cùng một After Authentication Process. Chỉ giá trị Application Setting khác nhau theo môi trường.
Vì sao không nên dùng URL do user truyền vào?
Post-Logout URL là một redirect target. Nếu cho phép user tự truyền URL này qua parameter,
bạn có thể tạo ra rủi ro open redirect.
Ví dụ nguy hiểm:
https://app.example.com/logout?redirect_to=https://evil.example.com
Nếu ứng dụng tin giá trị này và redirect trực tiếp, attacker có thể lợi dụng domain của bạn
để điều hướng user đến website độc hại.
Vì vậy, Post-Logout URL nên đến từ nguồn tin cậy:
- Application Setting do developer/admin kiểm soát.
- Bảng cấu hình nội bộ có whitelist domain.
- Cấu hình môi trường trong CI/CD pipeline.
Không nên lấy trực tiếp từ request parameter do user nhập.
Kiểm tra URL trước khi dùng
Với hệ thống yêu cầu bảo mật cao, bạn có thể kiểm tra URL trước khi ghi vào item.
Ví dụ đơn giản:
declare
l_url varchar2(4000);
begin
l_url := apex_app_setting.get_value('POST_LOGOUT_URL');
if l_url is null then
raise_application_error(-20001, 'POST_LOGOUT_URL is not configured.');
end if;
if not (
l_url like 'https://dokhala.com/%'
or l_url like 'https://test.dokhala.com/%'
or l_url like 'https://dev.dokhala.com/%'
) then
raise_application_error(-20002, 'POST_LOGOUT_URL is not allowed.');
end if;
apex_session_state.set_value(
p_item => 'AI_POST_LOGOUT_URL',
p_value => l_url
);
end;
Cách này giúp tránh cấu hình nhầm sang một domain không mong muốn.
Ứng dụng với CI/CD pipeline
Nếu bạn có pipeline deploy APEX app, Application Setting có thể được cập nhật theo từng môi trường.
Ví dụ ý tưởng:
begin
apex_app_setting.set_value(
p_name => 'POST_LOGOUT_URL',
p_value => 'https://dokhala.com/logout-complete'
);
end;
Tùy phiên bản APEX và quyền sử dụng API, cách cập nhật setting có thể khác nhau.
Nhưng nguyên tắc vẫn là: pipeline nên quản lý giá trị theo môi trường,
thay vì developer chỉnh tay Authentication Scheme sau khi deploy.
Trường hợp dùng bảng cấu hình riêng
Application Setting là cách gọn và đúng tinh thần APEX.
Nhưng trong một số hệ thống, bạn có thể muốn lưu cấu hình theo bảng riêng.
Ví dụ:
create table app_environment_config (
config_name varchar2(100) primary key,
config_value varchar2(4000),
updated_at timestamp with time zone default systimestamp
);
Sau đó process đọc:
select config_value
into l_url
from app_environment_config
where config_name = 'POST_LOGOUT_URL';
Cách này phù hợp nếu bạn đã có bảng quản lý cấu hình tập trung.
Tuy nhiên, với đa số ứng dụng APEX, Application Setting là lựa chọn gọn hơn.
Public page sau logout nên làm gì?
Page sau logout nên là page công khai và đơn giản.
Ví dụ:
- Hiển thị thông báo “Bạn đã đăng xuất thành công”.
- Có nút “Đăng nhập lại”.
- Không tự động redirect ngay về trang yêu cầu đăng nhập.
- Không gọi process cần session authenticated.
- Không hiển thị dữ liệu nhạy cảm.
Nếu sau logout bạn redirect thẳng về home page có yêu cầu đăng nhập,
ứng dụng có thể kích hoạt lại login flow ngay lập tức,
đặc biệt với Social Sign-In hoặc SSO.
Lưu ý với Social Sign-In và Identity Provider
Nhiều identity provider yêu cầu khai báo trước danh sách redirect URL hợp lệ.
Vì vậy, URL bạn cấu hình trong APEX cũng cần khớp với URL được đăng ký phía provider.
Ví dụ, nếu production dùng:
https://dokhala.com/logout-complete
Thì identity provider cũng cần cho phép URL này trong cấu hình logout redirect hoặc post logout redirect.
Nếu URL không khớp, logout có thể thất bại hoặc provider có thể chặn redirect vì lý do bảo mật.
Debug khi logout không đi đúng URL
Nếu logout không redirect đúng, hãy kiểm tra:
- Application Setting
POST_LOGOUT_URL có đúng giá trị chưa?
- After Authentication Process có chạy không?
- Application Item
AI_POST_LOGOUT_URL có giá trị trong session không?
- Authentication Scheme có đang dùng
&AI_POST_LOGOUT_URL. không?
- Page sau logout có public không?
- Identity provider có cho phép post logout redirect URL này không?
- URL có đang trỏ nhầm DEV/TEST/PROD không?
Bạn có thể tạm thêm debug trong After Authentication Process:
apex_debug.info(
'POST_LOGOUT_URL = %s',
apex_app_setting.get_value('POST_LOGOUT_URL')
);
Không nên log dữ liệu nhạy cảm, nhưng URL logout công khai thường có thể dùng để kiểm tra cấu hình.
Checklist triển khai
- Tạo Application Setting
POST_LOGOUT_URL.
- Bật tùy chọn giữ giá trị khi upgrade/import nếu phù hợp.
- Tạo Application Item
AI_POST_LOGOUT_URL.
- Tạo Application Process chạy After Authentication.
- Copy setting vào session state bằng
apex_session_state.set_value.
- Cấu hình Post-Logout URL dùng
&AI_POST_LOGOUT_URL..
- Đảm bảo URL trỏ đến public page.
- Đăng ký URL tương ứng trong identity provider nếu cần.
- Kiểm tra riêng DEV, TEST và PROD.
- Không lấy redirect URL từ user input chưa kiểm soát.
Best practice
- Không hard-code Post-Logout URL nếu ứng dụng có nhiều môi trường.
- Dùng Application Setting cho cấu hình phụ thuộc môi trường.
- Dùng Application Item để đưa giá trị vào session state.
- Chỉ cho phép URL đáng tin cậy.
- Không dùng request parameter làm redirect target nếu chưa validate.
- Page sau logout nên là public page đơn giản.
- Không redirect ngay về page bắt buộc login nếu dùng SSO.
- Đưa kiểm tra Post-Logout URL vào checklist deploy.
- Đăng ký đầy đủ post logout redirect URL trong identity provider.
- Test logout sau mỗi lần deploy authentication-related changes.
Kết luận
Dynamic Post-Logout URL là một pattern nhỏ nhưng rất hữu ích trong các ứng dụng Oracle APEX dùng SSO,
Social Sign-In hoặc identity provider bên ngoài.
Thay vì hard-code URL trong Authentication Scheme và phải chỉnh tay sau mỗi lần deploy,
bạn có thể lưu URL trong Application Setting, copy vào Application Item sau khi user đăng nhập,
rồi dùng item này làm Post-Logout URL.
Cách làm này giúp ứng dụng dễ triển khai qua nhiều môi trường hơn,
giảm lỗi cấu hình, phù hợp hơn với CI/CD pipeline và an toàn hơn nếu URL được kiểm soát đúng cách.
Điểm cần nhớ là Post-Logout URL là một redirect target.
Vì vậy, nó phải đến từ nguồn đáng tin cậy, không nên lấy trực tiếp từ user input,
và phải được kiểm tra kỹ trong quy trình deploy production.