correct way to log a user in programmatically

136 views
Skip to first unread message

Eirik Rosvold Larsen

unread,
Jan 24, 2011, 6:10:44 AM1/24/11
to lif...@googlegroups.com
Hi all,

I've browsed the "exploring lift" book and forums on how to log a user in programmatically, and all sources suggests using User.logUserIn(user)

However, in my rest-api authentication I can't get this to work. I'm following the example in "Listing 9.15: Performing Basic Authentication" of exploring lift and modified it to print out the currently logged in user. It prints "Empty" (my users are called workers).

 LiftRules.authentication = HttpBasicAuthentication("myApp") {
    case (workerEmail, workerPass, _) => {
      Worker.find(By(Worker.email, workerEmail)).map{
        (w: Worker) =>
          if (w.password.match_?(workerPass)) {
            Worker.logUserIn(w)
            println(Worker.currentUser)
            userRoles(AuthRole("worker"))
            true
          } else false
      }.openOr(false)
    }: Boolean
  }

When the request hits the rest-api, Worker.currentUser is still Empty.

When I do a form-based login (generated from Worker.sitemap, url http://localhost:8080/user_mgt/login) followed by an access to the rest api, something strange occurs:
In the authentication, function above, Worker.currentUser still prints Empty. However, when the request hits the rest-api, Worker.currentUser prints the user I logged in through the form with.

Could someone please explain why currentUser is not set immediately after a call to logUserIn?
Or rather: how do I correctly log in programmatically with basic authentication?

Regards, Eirik

Eirik Rosvold Larsen

unread,
Jan 24, 2011, 7:37:01 AM1/24/11
to lif...@googlegroups.com
Solved temporarily by using my own RequestVar to hold the logged in user. SessionVar didn't work (maybe because I'm setting it from the auth function?) Also, I did not let the RequestVar extend CleanRequestVarOnSessionTransition.

If anyone got a better solution, please let me know.

-Eirik

Timothy Perrett

unread,
Jan 24, 2011, 9:12:51 AM1/24/11
to lif...@googlegroups.com
User.logUserIn is not designed to be using with HTTP authentication like this out of the box. Are you using stateless dispatch? If so, thats why session vars "dont work".

Cheers, Tim

Derek Chen-Becker

unread,
Jan 24, 2011, 12:32:37 PM1/24/11
to lif...@googlegroups.com
Right, in the PocketChange source we're using stateful dispatch (e.g. LiftRules.dispatch). I'll add a note in the chapter pointing that out.

Derek

On Mon, Jan 24, 2011 at 7:12 AM, Timothy Perrett <tim...@getintheloop.eu> wrote:
User.logUserIn is not designed to be using with HTTP authentication like this out of the box. Are you using stateless dispatch? If so, thats why session vars "dont work".

Cheers, Tim

--
You received this message because you are subscribed to the Google Groups "Lift" group.
To post to this group, send email to lif...@googlegroups.com.
To unsubscribe from this group, send email to liftweb+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/liftweb?hl=en.

Eirik Rosvold Larsen

unread,
Jan 24, 2011, 3:21:52 PM1/24/11
to lif...@googlegroups.com
I'm using stateful dispatch.

On Mon, Jan 24, 2011 at 3:12 PM, Timothy Perrett <tim...@getintheloop.eu> wrote:
User.logUserIn is not designed to be using with HTTP authentication like this out of the box. Are you using stateless dispatch? If so, thats why session vars "dont work".

Cheers, Tim

--

Eirik Rosvold Larsen

unread,
Jan 24, 2011, 3:37:57 PM1/24/11
to lif...@googlegroups.com
Thanks for the hint. I tried both LiftRules.dispatch.prepend and append (doesn't really matter does it?) but the logged in user still cannot be retrieved from User.currentUser.

To be fair, I checked out pocketchange from tweir at github. I modified to use DispatchRestAPI instead of RestHelperAPI, and changed the first pattern match in the dispatch method to print the current user:

    case Req(List("api", "expense", Expense(expense,_)), _, GetRequest) =>
      () => println(User.currentUser.toString);Full(toXML(expense)) // default to XML

It too prints Empty, even after the user has been "logged in" in the authentication function in Boot.

To me (as a relatively new Lifter) it seems that User.logUserIn is a bit misleading in it's naming. The method doesn't always do what it's name implies, but rather logs the user in if a certain criteria has been fulfilled (a criteria I'm not familiar with - something to do with when in the lift lifecycle it's being called?)


Tim wrote:
User.logUserIn is not designed to be using with HTTP authentication like this out of the box.
When is it safe to call, i.e when does it do what its name says?

Regards, Eirik

Derek Chen-Becker

unread,
Jan 24, 2011, 3:39:24 PM1/24/11
to lif...@googlegroups.com
Well, it worked at some point in PocketChange. It's possible that something changed that is breaking it, so let me test locally and see if I can figure out what's going on.

Derek

Derek Chen-Becker

unread,
Jan 24, 2011, 4:28:44 PM1/24/11
to lif...@googlegroups.com
OK, I figured it out. What I had been testing only used the "userRoles" RequestVar and not the User.currentUser, so it was all passing. I'll update the book to reflect reality and my apologies for the confusion. Long-term, I think that it would be useful for ProtoUser to define both a SessionVar and RequestVar for currentUser so that stuff like this just works.

Derek

Derek Chen-Becker

unread,
Jan 24, 2011, 4:38:09 PM1/24/11
to lif...@googlegroups.com
Interestingly enough, ProtoUser.currentUser is backed by a RequestVar (ProtoUser.curUser), but that doesn't get set when logging in. Let me take a look and see if we can fix that.

Derek

Eirik Rosvold Larsen

unread,
Jan 25, 2011, 1:32:15 AM1/25/11
to lif...@googlegroups.com
Interestingly enough, ProtoUser.currentUser is backed by a RequestVar (ProtoUser.curUser), but that doesn't get set when logging in. Let me take a look and see if we can fix that.
Yeah I was a bit confused by that too, until I saw that it was a RequestVar with CleanRequestVarOnSessionTransition

-Eirik

 

Derek Chen-Becker

unread,
Jan 25, 2011, 11:26:24 AM1/25/11
to lif...@googlegroups.com
I'm going to have to double-check, but I think that CleanRequestVarOnSessionTransition only gets triggered when the session gets set up or torn down. We don't have a Session at this point yet, so the RequestVar should hold it. What I was thinking is that ProtoUser.curUser could be set with the logged in user and then when the session gets set up it will reset to its normal value, namely userFromStringId.

Derek

Derek Chen-Becker

unread,
Feb 14, 2011, 6:33:15 PM2/14/11
to lif...@googlegroups.com
Reply all
Reply to author
Forward
0 new messages