5

In my play! app,I have coded the controllers.Security as

class Security extends controllers.Secure.Security {
...
   static void onDisconnected() {       
       Application.index();
   }
   static void onAuthenticated() {
      User user = User.find("byEmail",Security.connected()).first();
      if(user.isAdmin()) {
         Admin.index();
      }else {
          System.out.println("onAuthenticated()::user not admin");
   }
}

I have set the routes as

GET     /admin/?              Admin.index
*       /admin                module:crud
GET     /                    Application.index

When I am on a page say pageX and click on the login link,the login form appears and I am able to login.If I login as admin ,it takes me to the Admin.index() and thereby to Admin/index.html view.So far so good

But,when I am on pageX,and click on login link,I expect to come back to pageX.Instead ,the Application.index() method is called and I am taken to the Application.index.html.. Is this the expected behaviour? What do I have to do to get to pageX after login?

update:

I tried storing the url in flash using the @Before in Security controller

class Security extends controllers.Secure.Security {
   @Before
   static void storeCurrentUrl() {
      System.out.println("storeCurrentUrl()");
      flash.put("url", "GET".equals(request.method) ? request.url : "/");
   }
   static boolean authenticate(String username, String password) {
   ...
   }

   static void onAuthenticated() {
      ...
      String url = flash.get("url");
      System.out.println("url="+url);
      if(!user.isAdmin()) {
         if(url!=null) {
        System.out.println("url not null");
        redirect(url);
     }else {
       System.out.println("url null  ..go to /");
       redirect("/");
    }
      }
   }

When I login,I get these terminal output

url=null
url null  ..go to /
index()

I have put the login/logout links in main.html template which is inherited by all other pages

<div id="main">
    <div class="auth">
     <a href="@{Admin.index()}">Go to Admin Area</a><br/><br/>
     <a href="@{Secure.login()}">Login</a><br/><br/>
     <a href="@{Secure.logout()}">Log out</a>
</div>
Damon Julian
  • 3,829
  • 4
  • 29
  • 34

3 Answers3

7

In you controller, before calling 'login()' put the 'url' into flash something like:

flash.put("url", "GET".equals(request.method) ? request.url : "/");

Once successfully logged in, get the 'url' and redirect.

String url = flash.get("url");
redirect(url); //you may redirect to "/" if url is null
sojin
  • 4,527
  • 2
  • 37
  • 40
  • thanks for the reply..however when I tried this,I am getting the url as null.It seems that @Before is not executed.I have updated the question..Will you please take a look? – Damon Julian Sep 05 '11 at 06:15
  • To get @Before method called, it should be part of the same Controller where incoming action is defined. Here storeCurrentUrl() is not in a Controller where login() action is defined. Hence storeCurrentUrl() will never get called. – sojin Sep 05 '11 at 13:13
  • 1
    Your case going to be bit tricky, as Play being stateless, it never store the url to your current page (pageX) to be referenced on next request. One way could be (though I feel its bit off the track) you could keep current page url in flash whenever that page get delivered, so that it will be there in flash for a redirect upon next request (on failed authentication). – sojin Sep 05 '11 at 13:30
0

This will be the expected behaviour as this is the way your routing is setup. Click on login and get redirected to Application.index or Admin.index if admin user.

If you want to retrieve the page which you clicked the login link from you could add the current action to the login link and once authenticated redirect to this action.

ie. login link: GET /login?action=Application.something --> takes you to login page then save action as a hidden field in your login form. When you authenticate the user render the action.

emt14
  • 4,846
  • 7
  • 37
  • 58
-2

Play already do redirection to original url when you try to access a protected page while not logged in.

If you want to reuse this, you ca put your url in flash scope in the "onAuthenticated" method. In the source code, play call "redirectToOriginalURL" just after that based on the value of the "url" value.

static void onAuthenticated() {
    flash.put("url", "GET".equals(request.method) ? request.url : "/");
}
Seb Cesbron
  • 3,823
  • 15
  • 18
  • 2
    by the time you reach onAuthenticated(), the request.url will be login() form action :) – sojin Sep 05 '11 at 13:32