Tuesday, July 10, 2007

Oracle APEX behind the Scenes: Logout Procedure

I was catching up with the forum when I spotted this thread: Adding a Process to Logout

Scott Spadafore, Oracle ACE and one of the developers of APEX, especially in the security area, explained what happened when you click the logout link in your Oracle APEX application.
(so for this post all credits go to him)

The built-in item LOGOUT_URL gives you access to the logout URL attribute of the current authentication scheme.
In referencing it as &LOGOUT_URL. or v('LOGOUT_URL'), or as a bind variable, the resulting attribute will have had basic substitutions performed on it first, e.g., for &APP_ID. and &APP_SESSION., facilitating its typical use as the target of a Navigation Bar Entry.

The standard logout URL (before substitutions) looks like:
wwv_flow_custom_auth_std.logout?p_this_flow=&APP_ID.&p_next_flow_page_sess=&APP_ID.:1
If you hover over this link in your application, you'll see that it's a full URL (host:port/pls/DAD/...) with substitutions completed and that the result of using the link is to execute the wwv_flow_custom_auth_std.logout procedure through modplsql.

Let's review the standard machinery:
What does the logout procedure do?
  1. Unsets your application's session cookie (actually sets it to '-1') and 2) redirects to the after-logout page.

  2. How does it know what cookie to unset?
    ...The cookie name is also an attribute of the curent application's authentication scheme so it looks it up.

  3. How does it know what the current application is since the logout procedure is not run in a "page request context"?
    ...The current application ID is a input parameter to the logout procedure (&p_this_flow=&APP_ID.).

  4. How does it know what page to show after logout?
    ...That's the other input to the logout procedure (&p_next_flow_page_sess=&APP_ID:1 where the application and page to redirect to are both given).

  5. But it looks like it goes to page 101 (login page) after logout.
    ...Yes, but the instructions were to redirect to page 1 after logout and if page 1 requires authentication, you have to login first. After login, you'll go to page 1.

How to create a custom logout procedure or call some DML during the logout operation?

A good way to do that is to change the logout URL in the authentication scheme to simply be a URL to a page in your application, say page 99:

f?p=&APP_ID.:99:&APP_SESSION.

On page 99 create a before-header process to call your DML procedure (or do the DML in the page process directly).
Then create a second process on the page (also an on-load vs. an after-submit process) that does:

apex_application.g_unrecoverable_error := true; 
wwv_flow_custom_auth_std.logout( p_this_flow=>:APP_ID,p_next_flow_page_sess=>:APP_ID ':1');
That should do it...

3 comments:

rpkumar said...

thanx its really helpful
visit: it may help u.
http://www.richonet.com
http://www.bwtrp.com
http://www.oracledba.in
oracledba.in

llenrup said...

Missing a concat symbol (||) before the ':1"

Departamento Mar del Plata said...

Thanks Dimitri!

I will add that second process for Apex version 22 works with that code:

apex_session.delete_session;
apex_util.redirect_url('f?p=' || :app_id || ':9999');