Contents

Users of APEX applications sometimes get logged out of the active session when they open APEX application links sent by another person. This can get quite frustrating, but thankfully, there are ways to get around this problem.

Logging out of an active APEX application session can sometimes be frustrating for users who – for example – click on an application link that is part of an email message. Users would like to avoid logging in again when opening an application link. Ideally, they would also like to be able to work in several browser tabs at the same time without worrying about the session state being overwritten. In this article, I’ll show how to create links that will allow you to work on an active session of an APEX application, and clone it if necessary.

APEX active session – defining the problem

By default, there is only one APEX session assigned per browser client and APEX application (there is also a session sharing feature that allows you to share sessions across several applications based on cookies, but I won’t cover that topic here for simplicity’s sake).

This is a big problem when you want to send a link to the application or specific pages in the application via email or a communicator. By default, the user will be logged out of the active session after clicking on a link shared by another person. Usually, this happens because the link sent by another person contains a session ID different from the active session ID of the user clicking the link. There are also situations where the link does not contain any session ID at all. In both cases, the user will be logged out, which may get quite frustrating for people who like to work within the same session and preferably within several tabs.

Fortunately, there’s a way to circumvent this problem. Want to know what it is? Read on!

Rejoin Sessions setting

Before I get into the specific problems and their solutions, along with examples, I must mention an issue that will be common and required for each of the problems described in this article – Rejoin Sessions.

To be able to talk about using an existing user session at all, it is necessary to set the Rejoin Sessions setting to Enabled for All Sessions at the application level (Shared Components -> Security Attributes -> Session Management tab) or specific page in the Security section. When this setting is set to the aforementioned value, APEX will start using cookies to use the existing session.

It’s worth noting that the Rejoin Sessions setting at the application or APEX page level is overridden by the settings at the APEX instance level (Manage Instance -> Security -> Security tab). This means that if Rejoin Sessions at the instance level is set to Disabled, you will not be able to change this setting at the application level.

Security considerations

Additionally, changing the Rejoin Sessions setting exposes the application to security breaches. Below is a quote from the help text for the Rejoin Sessions setting:

Enabling rejoin sessions exposes your application to possible security breaches, as it can enable attackers to take over existing end-user sessions. To learn more, see the Rejoin Sessions sections in “Managing Application Security” in the App Builder User’s Guide.”

Therefore, if you want to allow Rejoin Sessions, you should first take care of your system’s security.

Case 1 – links without parameters

So let’s move on to the specific cases that I will present and discuss using the slightly modified Customers app available in the Apps Gallery. In each example, I will create an APEX item containing a corresponding link that could be used in an email message.

The first case I’ll detail will be about links without parameters – it’s the simplest of the discussed examples. Links of this kind are also relatively safe because they do not pass values that could be swapped, causing access to data that should not be seen by the user.

Links without parameters can be useful – for example – if we want to send emails about notifications in applications available under the notification bell icon on the top navigation bar. In such a situation, we usually want to direct the user to the appropriate application/environment in which they should be notified. Such a link usually leads to the home page and has no parameters.

So let’s move on to the implementation of the above example. At Page 59 (Customers), I set the Rejoin Sessions attribute in the Security section to Enabled for All Sessions.

A screen showing the APEX settings.

In the next step, I build a link to the home page of my application, which could then be used when sending an email. In my example, I will simply make a region and an APEX item that will display the URL to the Customers page. So I add an APEX item named “P59_HOME_URL” and in the Default section, I enter the following PL/SQL Expression:

APEX_UTIL.HOST_URL || APEX_UTIL.PREPARE_URL(p_url => 'f?p=' || :APP_ID || ':59')

A screen showing the PL/SQL expression.

This will generate a URL (note that it does not contain a session ID) which, when typed into the browser bar, will not log the user out of the active session because APEX will use an existing session cookie for this application.

A screen showing the customers page.

Case 2 – links with parameters

The second example I would like to present is about links with parameters. In this case, you need to take care of security to avoid changing parameters in the link, which could result in the users accessing information that they shouldn’t see.

Links with parameters may be used in a situation when we want to redirect a user to a specific page. For example, it may present details of an order placed in our application (an Internet store), or the client’s data and all information connected with it. In both cases, the link should lead directly to the data that interests the person clicking the link without the need to search through a large number of rows in search of the relevant customer/order.

In my second example, I will use a page that presents information about the customer. On the Customer page (page 50), similarly to page 59, I set the Rejoin Sessions attribute in the Security section to Enabled for All Sessions. This time it won’t be so easy because attribute links with parameters require the following:

  • setting Session State Protection to Enabled at the application settings level (Shared Components -> Security Attributes -> Session State Protection tab);
  • The URL with the parameters must have a valid checksum.

If any of these conditions are not met, the user will not be redirected to the appropriate page using the existing session.

In the case of my example, Session State Protection is enabled. Additionally, I have the Page Access Protection attribute set to Arguments Must Have Checksum to prevent access to data if a valid checksum is not provided. So the only thing I still need to take care of is the valid checksum in the URL. Just like on page 59, I will add a new region and create an APEX item named “P50_URL_WITH_PARAM” to display the link. I set the value of the item using the following PL/SQL Expression (you can find a description of parameters and checksum types below, in the subsection about the APEX_UTIL.PREPARE_URL function):

APEX_UTIL.HOST_URL || APEX_UTIL.PREPARE_URL( 

    p_url => 'f?p=' || :APP_ID || ':50::::50:P50_ID:' || :P50_ID,

    p_checksum_type => 'PUBLIC_BOOKMARK',

    p_plain_url => true

)

A screen showing the code editor.

Our link is practically ready. The last step is to change the Session State Protection attribute of the “P50_ID” item to Checksum Required – Application Level. This change is necessary if the checksum type of the built link is set to PUBLIC_BOOKMARK.

Done! Time for testing. Let’s assume that the part of the application I’m currently working on is the Partners page (the top window from the screenshot below). While I’m working, I get an email that there have been changes to the Illumina Biotech client page (e.g. a new activity has been added) along with a link to the client details page (URL included in the “P50_URL_WITH_PARAM” item) so that I can quickly move there. When I click on the link, I will be redirected to the customer details without losing my existing session (bottom window on the screenshot below).

A screen showing the partners page.

It’s worth noticing that the link which would eventually be used – for example – in an e-mail does not have a session number because I’m not able to predict what the session ID of the user who clicks the link will be, and I don’t know when the link will be clicked. Including the session ID in the link would cause the user to log out if the ID was different from the one the user has in the active session, and I want to avoid that.

APEX_UTIL.PREPARE_URL – function parameters and checksum types

According to the documentation, the PREPARE_URL function from the APEX_UTIL package contains the following parameters:

  • p_url – an APEX navigation URL. Here you can specify the target page and the names and APEX values of the items you want to set;
  • p_url_charset – the character set name. In the case of my example, I use the default value;
  • p_checksum_type – the checksum type. The most important parameter in the context of avoiding logging out from the active session. The default value is null, but it can take other values as well:
    • PUBLIC_BOOKMARK or 1 – use this value when you want to generate a link that will be available to all users, like the one used in an email message. It’s not related to the user session or the user who generates the link.
      • This means that if user Mark generates such a link, he can successfully send it to user Sam, and Sam’s clicking on the link will not cause him to be logged out of the active session (assuming the conditions in the Links with parameters section have been met).
  • PRIVATE_BOOKMARK or 2 – use this value when you want to generate a private link that will only be available to you. It’s associated with the currently authenticated user.
    • This means that if Mark generates such a link and saves it, he will be able to click on it in a few days and that clicking on the link will not log him out of his active APEX session. If, on the other hand, he sends this link to Sam, Sam will be logged out of his active session because the link Mark sent him is private.
  • SESSION or 3 – the last value is used when you want to avoid being logged out from the session that was active when the link was created. It’s related to the user’s active session at the moment of creating the link.
    • This means that if Mark generates such a link for himself, he will be able to use it until the active session expires – clicking on the link will not log Mark out. If, on the other hand, Mark generates a link with session number 1 active, then logs out of the application and logs back in (creates session number 2), then clicking on the link will log Mark out of session number 2 because the link was created in session number 1.
  • p_triggering_element – a jQuery selector. This is required for Modal Dialog support. In my case, I use the default value;
  • p_plain_url – a flag indicating if JavaScript code should be added in case the function is called from the modal dialog level. In my case, I set this value to true because I want to avoid adding additional JavaScript code since I call this function from a normal page.

Case 3 – links with parameters and Session Cloning

Cloning an APEX session is the last example I would like to present. It’s also an extension of the topic on links with parameters. Session cloning helps you avoid the problem of overwriting item values in a session by copying their current value to a new session. This way, users of the application are able to work on several tabs at the same time.

Session cloning would certainly be useful in the situation I described above in the parameter links section. For example, a user who accesses the data of a customer, or information about a specific order, would like to avoid overwriting the data about another customer/order, which is opened in another tab. Session cloning gives you that option.

To clone an APEX session, it is necessary to set the CLONE_SESSION_ENABLED parameter to Y at the APEX instance level. See the official documentation for more information.

So let’s move on to the last example, for which I will use the same page that I used in case 2 – the one that presents information about the customer.

First, on the Global Page, I create a region named “Global items container”, set its Template to Blank with Attributes, and create an APEX item of the Hidden type named “P0_CLONE_SESSION” within this region. Finally, I set the Session State Protection attribute of the “P0_CLONE_SESSION” item to Checksum Required – Application Level.

A screen showing the App Builder.

At this point, I have the APEX item ready, which will be a flag informing whether to clone the APEX session (e.g. when clicking a link that is part of an email that opens the application page in a new tab) or not.

The next step is to create a process responsible for cloning the session when the value of the “P0_CLONE_SESSION” entity is equal to Y.

On the Customer page (50), in the Pre-Rendering section, and the Before Header sub-section, I create a process named “Clone APEX session”. In the Server-side Condition section, I set Type to Item = Value. In the Item field, I enter the “P0_CLONE_SESSION” value, and in the Value field, I enter the Y value. I then provide the following PL/SQL code that will be executed by the process:

  :P0_CLONE_SESSION := 'N'; -- Set 'N' for current (not cloned) session




    APEX_UTIL.REDIRECT_URL(

        p_url => APEX_UTIL.HOST_URL || APEX_UTIL.PREPARE_URL( 

                    p_url           => 'f?p=' || :APP_ID || ':50:SESSION:APEX_CLONE_SESSION::50:P0_CLONE_SESSION,P50_ID:N,' || :P50_ID,

                    p_checksum_type => 'PUBLIC_BOOKMARK',

                    p_plain_url     => true

                )  || '&session=' || :APP_SESSION

    );

end;

A screen showing the code editor.

Then I duplicate the APEX item named “P50_URL_WITH_PARAM” and set the name of the duplicated item to “P50_URL_WITH_PARAM_AND_CLONE”. In this item, I will display a link, which – in conjunction with the process defined above – will clone the session, in addition to redirecting to the target page. I set the value of this item using the following PL/SQL Expression:

APEX_UTIL.HOST_URL || APEX_UTIL.PREPARE_URL( 

    p_url           => 'f?p=' || :APP_ID || ':50::::50:P0_CLONE_SESSION,P50_ID:Y,' || :P50_ID,

    p_checksum_type => 'PUBLIC_BOOKMARK',

    p_plain_url     => true

)

Additionally, I add an APEX item called P50_SESSION_ID that will show me the session ID.

Done! Before I move on to testing, I’ll explain once more how this solution works. The APEX item named “P50_URL_WITH_PARAM_AND_CLONE” holds the link to the destination page (in my application this is the customer data). This link could be used in an email message, for example. Aside from the ID of the customer whose data I want to display, it contains a “flag” with the value Y for the “P0_CLONE_SESSION” item. This will start a process that clones the session because the condition in Server-side Condition is met. This process will redirect to the same page with the APEX_CLONE_SESSION request, which will clone the session, but only if a session number is specified in the link. That’s why I included the session number at the end of the link – because the APEX_UTIL.PREPARE_URL function will automatically get rid of it. After the redirect, the session is cloned.

Time for testing. I log into the application and am assigned a session ID of 15637848892753. I go to the Illumina Biotech client page and copy the link generated by the item named “P50_URL_WITH_PARAM_AND_CLONE” (top browser window in the screenshot below). I paste this link into a new tab expecting to see the same client data displayed but in a cloned APEX session (bottom browser window in the screenshot below).

A screen showing the customers page.

It worked! The session has been cloned, so the user can safely modify the data without worrying about overwriting item values as would happen with a shared session.

Annotations

  • This article is based on APEX version 21.2 with the Friendly URLs setting enabled. If you are using a different version of APEX that doesn’t support Friendly URLs you may need to adapt the above examples to your version of APEX and the problem you are trying to solve.
  • Also, check whether in your particular case the APEX_UTIL.HOST_URL function doesn’t require the appropriate parameter value, in order for the prepared link to work without any problems.

APEX active session – conclusion

As you can see, there are ways you can use to solve problems with sessions and prevent the need for users to log in again when they open an application link. What’s more, they really aren’t that hard to implement. With a little bit of time and work, you can set your application up the way you want.

It’s worth pointing out that in APEX 22.1 there is also a feature called Persistent Authentication which should solve at least some of the problems described in this article. I haven’t had a chance to test it yet but I’m sure I’ll do it soon and share my impressions in my next blog post!

If you’re interested in more APEX-related content, check out some of the other articles on our blog:

  1. How to integrate Stripe with an Oracle APEX application: Step-by-step guide
  2. Oracle APEX new features – the low-code platform keeps evolving
  3. Google Identity Services – a quick guide on using the new library in Oracle APEX applications
  4. What is Oracle APEX? Possibilities and career paths for low-code developers
Share