And another thing ...
Oracle & Apex Geekery
Friday, October 12, 2012Remember Me APEX Autologin
I promised to publish about this subject to one of the attendees during my presentation at KScope 12 in San Antonio. I used this functionality in my demo application (FifApex) and it seems there is interest in how to do this.Most of the public websites like Facebook, LinkedIn, Twitter, Amazon or OTN do have it: an option to stay logged in, even if you closed the browser, so you do not have to authenticate each time you visit the site again. I’m pretty used to it and would be surprised if a website didn’t offer this convenient feature. OK, it’s not entirely secure, but, as I said, very convenient.
I’m working on a “consumer” site/application, I’m building it with APEX and I want to offer this “remember me” option too. I knew an APEX based website that does offer this feature (www.plsqlchallenge.com) and I had a chat with the developer that implemented it’s login mechanism, Broughton from Apex Evangelists. So, here my thanks to him for the original inspiration.
Oracle Application Express has neither a build in functionality nor is it providing a “standard” Authentication Schema that does provide this mechanism. But, with just a little effort you can implement this Autologin in your application. My example uses a Custom Authentication schema, meaning I have a user table and a package, providing all the necessary functionality. At the bottom of this post, you will find links, where you can download all files you need to install the demo application in your own environment. First of all, let me define the mechanism: the user gets an option, usually a checkbox, in login screen to stay signed in. Next time the use visits the site, he doesn’t have to provide his credentials and is automagically signed in. The common technique to achieve this, is using a cookie that holds a token to identify the returning user. So we have to set a cookie when the user signs into the application and check for the cookie and validate the token when the user comes back. Setting and reading a cookie is easy, using the OWA_COOKIE package, but how to integrate this into a APEX authentication schema? The following example is build with a standard “empty” application with Custom Authentication. Prior I created a table to hold the user data and a package, containing the authentication logic. Note: this is a simplified example, so using this in your production application is at your own risk! All code is included in the demo application download. CREATE TABLE my_custom_users( username VARCHAR2(25 BYTE) , password VARCHAR2(250 BYTE) , token VARCHAR2(25 BYTE) ); INSERT INTO my_custom_users(username, password, token) VALUES ('DEMO', my_cust_auth.encodeit('DEMO', 'demo'), NULL); COMMIT; First I’m going to modify the generated Login Page (101), adding the “Remember me” checkbox. Then I modify the “Set Username Cookie” process that already should exists and stores the APEX username in a cookie (I do not make any changes to this functionality): The code I add, checks, if the “Remember me” has been ticked by the user, the user actually is a valid user from my table and then sets a cookie, called “REMEMBER_ME”. The value of this cookie is generated by a function, producing a random string and storing this as a token with the user data or fetches the token from the user data, if already existing. In my example, I choose to set the expiration date of this cookie one to about a year.
Let’s start
Step 1: setting the cookie during login
Christian Rokitta Follow 144 View my complete profile About Me Home My Event Agenda Demo APEX Application themes4apex APEX.nl Your one stop Oracle APEX News & Blog site Pages The storm had now definitely abated, and what thunder there was now grumbled over more distant hills, like a man saying "And another thing…" twenty minutes after admitting he's lost the argument. And Another Thing ... The SmartPivot Plugin enables users to create multidimensional pivot reports using draganddrop functionality. Easily configure sub and grand totals just like in Excel, in any APEX application. APEX SmartPivot Plugin ► 2014 (2) ► 2013 (8) ▼ 2012 (11) ► December (1) ► November (2) Blog Archive «ﺔﻳﻟﺎﺗﻟﺍ ﺔﻳﻧﻭﺭﺗﻛﻟﻹﺍ ﺔﻧﻭﺩﻣﻟﺍ ﺩﻳﺯﻣﻟﺍ 5 ﻝﻭﺧﺩﻟﺍ ﻝﻳﺟﺳﺗ ﺔﻳﻧﻭﺭﺗﻛﻟﺇ ﺔﻧﻭﺩﻣ ءﺎﺷﻧﺇRunning the application, logging in with the checkbox ticked, you can exam the cookies of your APEX application by using a tool like the Developer Console of Chrome. Next to some cookies, set by APEX itself, you should find the “REMEMBER_ME” entry holding the token string and expire date of today + 365 days: Now, when do we need to read the “REMEMBER_ME” cookie again? Every time the visitor returns to your site/application, has not signed in yet (obviously, as we want to do this automagically) and the cookie is set and holds a token that is known in the user table (assuming that the user is the same again!). I want to perform the check, regardless of the page visited is a public page or a page that requires authentication. The event that should be triggered, if the conditions are met (cookie set and valid, user is public), is the a automatic login, similar to the original login. To perform the check, I will use “PAGE 0”, but lets first create the autologin functionality to be called:
To realize the autologin, I create a new page (103 in example application). This page only contains a “On Load Before Header” process and one page item. The process only fires, when the request name is “AUTOLOGIN” and calls the build in standard APEX login procedure provided for custom authentication. It uses the page item to “P103_TOPAGE” as target page after successful login, which I will set on the triggering process/branch on page 0, to return to the page the user actually requested in the URL. The username is derived from the cookie (the token belonging to one unique user) using the call OWA_COOKIE.get ('REMEMBER_ME'); in a stored procedure. wwv_flow_custom_auth_std.login( P_UNAME => my_cust_auth.get_user_from_cookie, P_PASSWORD => null, P_SESSION_ID => v('APP_SESSION'), P_FLOW_PAGE => :APP_ID||':'||:P103_TOPAGE );
Step 2: using the cookie on return
▼ October (1) Remember Me APEX Autologin ► September (1) ► August (2) ► June (1) ► April (1) ► March (2) ► 2011 (2) ► 2010 (7) ► 2009 (6) Oracle Application Express ... € 0,00 Oracle Application Express ... Pro Oracle Application Expr... Beginning Oracle Applicatio... Oracle Application Express ... Oracle Pl/Sql Best Practice... Oracle PL/SQL Programming Our Book: by Roel Hartman, Christian Rokitta and David Peake Books I did read (or should have read): Books ⇒ My PL/SQL Challenge Profile ⇒ ODTUG APEX Community ⇒ Oracle Application Express ⇒ Oracle Technology Network Subscribe ToAs you see, the password parameter is NULL. So I have to add logic to the Authentication Function (my_cust_auth.validate_user) of my custom Authentication Schema, that handles two cases: either a valid combination of username/password is given, or the “REMEMBER_ME” token is set and a corresponding user is found. Again: this is very basic and may not be sufficient for your production application.
I already mentioned that I will use Page 0 to call the auto login. Doing so, the user should be singed into the application, regardless which page he opens first. I simply create a “After Header” Region of type “Dynamic PL/SQL”. The redirect will be done using the APEX build in procedure sys.owa_util.redirect_url, passing the relative URL of page 103 with request parameter “AUTOLOGIN”. This region is conditional, checking for: user is public, cookie is set and belongs to “a” user. I added an extra condition checking for the current page ID to be less or equal to 101, to prevent page 103 from recursively calling itself. Page 102 will be this demo application’s special logout page (see next section). All “normal” pages in this application are assumed to have ID’s in the rage of 1 to 100. You definitely should modify this condition to meet your actual applications page ID ranges. Note to myself: I first tried to use a “BeforeHeader” Branch in Page 0 to implement this redirect. But: Branches in Page 0 do not
Step 3: automagically do it
Posts Comments Join this site with Google Friend Connect Members (30) More » Already a member? Sign in Followersever get executed. It’s not the first time I hit this pitfall. After all: the APEX 4.1 Application Builder Treeview of Page 0 suggests Branches are possible.
We need to offer the user a way to logout and remove the cookie. I create a new page, 102, containing one “On Load Before Header” process and a branch.
The process removes (expires and replaces value with empty string) the cookie and performs the actual logout using WW_FLOW_CUSTOM_AUTH_STD.LOGOUT. The branch will take the user to the (public) Home page (1).
I then specify to use page 102 as the Logout URL of my Authentication Schema.
The request name “LOGOUT” is provided by APEX itself, so you might check for it in a condition, rather then defining the process as unconditioned, just to prevent accidental logout. So, that’s it. Just a few simple modifications to your custom authentication. What do you think? Does anybody have a more elegant solution (I’m sure there are)? I would appreciate it, if you would post your ideas as comments to this article. If you haven’t got a solution yet, but want to use mine: go ahead! Down here the links of the demo application on apex.oracle.com and the full download of it for you as a template. Try the demo at apex.oracle.com! (login with demo/demo) Download the DemoApp! (just import and install incl. supporting object scripts; min. version: 4.1; default login: demo/demo) The whole mechanism is a rather simple and naïve approach. I just wanted to explain the basic principle of it. There are lots of enhancements and improvements one could think of, and actually, while writing this post I thought of some myself: using pre/post function call of Authentication Schema instead of page processes
Step 4: forget me
Demo and Download
Possible Enhancements:
Posted by Christian Rokitta at 4:21 PM Labels: APEX, autologin, login, remember
integrate autologin logic from page 103 to page 101 cookie name application variable or dynamically generated investigating the possibility of an autologin authentication plugin
11 comments:
David October 15, 2012 at 9:39 PM Thanks a lot for this. It's something I've wanted for a long time, but have never taken the time to actually figure out and implement! I've added it to my site, but without pages 102 and 103 (some careful conditions on page 101 allow everything to coexist happily). Also changed the page 0 condition to only fire on pages which require authentication.Reply
Christian Rokitta October 15, 2012 at 10:50 PM Hi David,
Good idea. I was thinking of integrating page 102 and 103 too.
The reason I did not constrain the autologin to page that require authentication is, that I wanted returning users to be logged in immediately, in case I want want to show personal information, like notifications, or menu items, that otherwise would be hidden. I guess, it depends on the purpose of your web site/application. As I said: it's a template or even less, just a howto. Regards, Christian Reply Richard Martens October 30, 2012 at 10:19 PM Hey Christian, I remember this subject was the first we had a discussion on, together with Sergei in Brussels. Great blog, I'll investigate soon. Regards, Richard Reply Dean Attewell May 8, 2013 at 4:59 AM Hi Christian I created a modified version of what you have, it doesn't have page 0 to redirect to autologin page. this was causing me issues.. I have 101, as my main login page, (so Apex automatically redirects to 101 (login) when not authenticated. but all it does is check cookie has token etc.. and if no valid cookie/token it redirects to another page with login/password, where it sets token cookie Works well Dean Reply Dean Attewell May 8, 2013 at 5:03 AM Hi Christian I made a modified version of your login.. after having difficulties with page 0 redirect.. My version doesn't have page 0 redirect.. I made my std login page the autologin page.. so apex automatically goes to this page when not authenticated.. And only runs 1 PL/SQL DECLARE c OWA_COOKIE.cookie; l_token eng_users.token%TYPE;
Replies Reply l_username eng_users.username%TYPE; BEGIN c := OWA_COOKIE.get ('REMEMBER_ME'); l_token := c.vals (1); Select username into l_username from eng_users where token=l_token; IF length(l_username)>0 THEN APEX_CUSTOM_AUTH.post_login (l_username, V('APP_SESSION'),:APP_ID||':1', TRUE); ELSE apex_util.redirect_url ('f?p=&APP_ID.:109:&SESSION.'); END IF; EXCEPTION WHEN OTHERS THEN apex_util.redirect_url ('f?p=&APP_ID.:109:&SESSION.'); END; So it redirects to a page with Username/Password if no valid cookie/token exists Reply joost May 15, 2013 at 4:51 PM Hi Christian, Thanks for you the blog. It works perfect on a desktop interface. But on a jquery mobile interface it doesn't work for me. Do you have an idea how to solve this. Thanks in advance. Grtz, Joost Reply Christian Rokitta May 16, 2013 at 11:16 AM Hi Joost, I have successfully implemented the approach in an APEX 4.1 application using jQueryMobile: http://m.fifapex.net.
One thing to keep in mind: the standard jQM way of getting a new page is fetching it using an AJAX call. The autologin functionality requires a HTTP call when logging in with the “rememberme” checkbox set, to set the tokencookie. In my application I disabled the AJAX behavior for the loginbutton by adding a jQM data attribute to it: dataajax="false". Hope this helps. Cheers, Christian joost May 18, 2013 at 10:41 PM Hi Christian, Thanks for your quick response. Indeed this solves the problem. Grtz, joost Reply Faraz Baloch March 29, 2014 at 12:29 PM Hi Christian, I m facing problem after importing the script into apex. When i try to connect to the application using the given credentials, i get an error "Invalid Login Credentials, Wait for 40 seconds".
Newer Post
Home
Older Post
Subscribe to: Post Comments (Atom) Replies Reply Enter your comment... Comment as: Google Account Publish PreviewSecondly, why are we using apex_authentication package for validation and how my_custome_users table is populated and how it is validated at the relogin time of user. Regards Faraz Saleem Reply Christian Rokitta April 3, 2014 at 11:17 AM Hi Faraz, Let's discuss this offline. Just send me an email (christian@rokitta.nl) describing the problem you are facing. Regards, Christian jeffkemponoracle.com August 9, 2014 at 4:58 PM Thanks very much for this. I read this back in 2012 when you first posted it and put it in my list of bookmarks to get to later well I finally got around to it :) Got it working quite well. I ended up putting the autologin code just on my home pages (desktop and mobile interfaces) which and put the AUTOLOGIN and LOGOUT request handlers on the login pages, instead of creating new pages for these functions. Apex 4.2 doesn't expose the Logout URL parameter in the authentication scheme so I just changed the Logout buttons to navigate to the login page with the LOGOUT request. Reply Powered by Blogger.