ProtoUser and sessions

74 views
Skip to first unread message

Nolan Darilek

unread,
Sep 1, 2010, 10:52:53 PM9/1/10
to Lift list
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

This is an odd one and I'm not sure what's up. I suspect it's similar to
my issue with ListenerManager a while back wherein User.currentUser
wasn't in scope when I was setting up an actor to listen.

Thanks to Tim's help and advice, I've got my web service doing basic
authentication and my mobile app authenticating against it. I have
various code that I want run based on whether or not the user is logged
in, and for that I generally do:

User.currentUser.map { u => // some side-effect here }

This works fine for users logged in via the web interface, but it fails
when logged in via the API. That is, none of the user-specific
customizations run.

My API is stateful, requiring users to get a session and use that for
all calls as a part of the URL. In fact, I have other session variables
that work just fine, preserving the previous results of calls to provide
richer context for the next one. I'm setting up my API like so:

LiftRules.dispatch.append(V1)

object GetSession {
def unapply(x:String) = S.request.map(LiftRules.getLiftSession)
}

object V1 extends RestHelper {

serve {
case Req("api" :: "v1" :: "session" :: _, "json", GetRequest) =>
getSession()
case r@Req("api" :: "v1" :: GetSession(s) :: "noop" :: _, "json",
GetRequest) => noOp(r, s)
case r@Req("api" :: "v1" :: GetSession(s) :: "position" :: _,
"json", GetRequest) => getPosition(r, s)
case r@Req("api" :: "v1" :: GetSession(s) :: "position" :: _,
"json", PostRequest) => setPosition(r, s)
}

def setPosition(r:Req, s:LiftSession) = S.init(r, s) {
for {
lt <- r.params.get("lat") failMsg("Parameter 'lat' missing")
lat <- tryo(lt.head.toDouble) compoundFailMsg("Parameter 'lat'
invalid")
ln <- r.params.get("lon") failMsg("Parameter 'lon' missing")
lon <- tryo(ln.head.toDouble) failMsg("Parameter 'lon' invalid")
} yield {
val params = Map[String, Double](
...

I even tried creating my own SessionVar and setting the user there in
onLogIn. I've confirmed that this method is being called, but when my
API update method is hit, both User.currentUser and my loggedInUser
SessionVars are empty. My previous state, on the other hand, works just
fine.

So what am I missing here? How do I inject User.currentUser into API
sessions as completely as it seems to be for sessions created from the
browser?

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAkx/EYUACgkQIaMjFWMehWJmxQCffZsdfygq/cU4jOBPyzNZJofI
NcQAnjRNG0gd805NmHEIzOFAxhBR8NLp
=wsM/
-----END PGP SIGNATURE-----

David Pollak

unread,
Sep 1, 2010, 10:59:30 PM9/1/10
to lif...@googlegroups.com
I suspect that the clients are not including the JSESSIONID cookie when they make subsequent calls.


--
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.




--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Blog: http://goodstuff.im
Surf the harmonics

Nolan Darilek

unread,
Sep 2, 2010, 12:25:25 AM9/2/10
to lif...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 09/01/2010 09:59 PM, David Pollak wrote:
> I suspect that the clients are not including the JSESSIONID cookie when they
> make subsequent calls.
>

Do they need to? I thought that was the whole point of including the
session in the URL, the GetSession extractor and the:

def noOp(r:Req, s:LiftSession):JValue = _S.init(r, s)_ {
""

At least, that's why I'm doing it all, as per advice gotten here a while
back when I started designing the API.

Thanks.


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAkx/JzUACgkQIaMjFWMehWLIHQCfRpBwxgEHYSfJlBNY3VSbxXZj
xUMAmwdlmt+TU48m9BU6JrRhB4ablUGC
=/nxY
-----END PGP SIGNATURE-----

David Pollak

unread,
Sep 2, 2010, 2:36:17 AM9/2/10
to lif...@googlegroups.com
On Wed, Sep 1, 2010 at 9:25 PM, Nolan Darilek <no...@thewordnerd.info> wrote:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 09/01/2010 09:59 PM, David Pollak wrote:
> I suspect that the clients are not including the JSESSIONID cookie when they
> make subsequent calls.
>

Do they need to? I thought that was the whole point of including the
session in the URL, the GetSession extractor and the:

def noOp(r:Req, s:LiftSession):JValue = _S.init(r, s)_ {
   ""

At least, that's why I'm doing it all, as per advice gotten here a while
back when I started designing the API.

If you can put together an example (runnable Maven or sbt project on GitHub), I'll look at it.
 

Thanks.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAkx/JzUACgkQIaMjFWMehWLIHQCfRpBwxgEHYSfJlBNY3VSbxXZj
xUMAmwdlmt+TU48m9BU6JrRhB4ablUGC
=/nxY
-----END PGP SIGNATURE-----

--
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.

Nolan Darilek

unread,
Oct 1, 2010, 1:01:24 PM10/1/10
to lif...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 09/02/2010 01:36 AM, David Pollak wrote:
>> If you can put together an example (runnable Maven or sbt project on
>> GitHub), I'll look at it.
>

Took me a while, but this is a side-project and the dayjob kept me busy.

http://github.com/ndarilek/lift-protected-api-test

I'm creating a basic REST API with a noop.json call. It's being appended
to LiftRules.dispatch, so I'd expect it to be called when the session is
initialized.

Only, as can be seen with:

curl -u test:test http://localhost:8080/api/noop.json

When I set the user session var from
LiftRules.httpAuthProtectedResource, it doesn't take. I guess this is
because sessions aren't set up yet.

This is a bit different from my actual use, though I don't know if those
differences are significant. I use a session as part of the URL path,
looking up the user's session that way. Using that is likely what would
be needed to make the second println work, the one which returns the
value of the session var from the noop API call, but given that I can't
even get the first println working, I didn't add session
lookup/initialization to the API.

Also, this uses session vars whereas my actual use case uses
User.currentUser. Either way, the results are the same.

I'm guessing that the session stuff isn't initialized at this point. If
that's the case, then how do I pass the authenticated user into the API
such that I can access user-specific data? I'm successfully
authenticating, but when my API itself is hit, it doesn't seem to see
the current user value.

Thanks.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAkymE+QACgkQIaMjFWMehWLypwCfcl0BWVh/0ghZoI1ZJUEvm5QX
OVgAn1PMl2EjsFFw4aD/0n0MxWWPwFKT
=ofi3
-----END PGP SIGNATURE-----

Nolan Darilek

unread,
Oct 22, 2010, 9:55:36 PM10/22/10
to lif...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hey folks. A while back, I had some issues with sessions created by HTTP
authentication not appearing to access some session variables. Since I
have a REST API that maintains state this way, I was finding it
difficult to support making the API a protected resource, storing the
authenticated user in a session variable or accessing User.currentUser.

I put together a sample project, as can be seen in the below message. It
seems like what's happening is that I'm attempting to assign a value to
a session variable in LiftRules, after my user is authenticated via HTTP
basic auth, but I'm guessing the session infrastructure isn't set up
yet. My API itself doesn't seem to have issues persisting data to
SessionVars and pulling it out in subsequent calls, so my issue seems to
be indicating to my API that a user is logged in.

Is there a way to do this with session variables? If not, then how do I
pass a user to my REST API?

See the quoted message below for details on the sample project. Thanks
for your time.

iEYEARECAAYFAkzCQJgACgkQIaMjFWMehWL3YQCghCIsMgsAssbp0zYlvHzLgCM/
tfEAnjWX9elGv+oYempaPa9XoGEjuRnC
=OWDO
-----END PGP SIGNATURE-----

David Pollak

unread,
Oct 23, 2010, 1:33:38 PM10/23/10
to lif...@googlegroups.com
Yes, sessions are not initialized this early in the HTTP request/response cycle.  However, RequestVars are.  My suggestion is to put User into a RequestVar and then in your API module, read the RequestVar and put it into a SessionVar.

-----END PGP SIGNATURE-----

--
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.

Nolan Darilek

unread,
Oct 24, 2010, 2:07:50 PM10/24/10
to lif...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Cool, thanks, this works perfectly. I had a bit of an issue in that I
was getting warnings about the RequestVar not being accessed sometimes
(I was only setting the user at my API's logical entry point) but a few
tweaks and cryptic battles with Scala later and I have it sorted.

Thanks.

- --


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<liftweb%2Bunsu...@googlegroups.com>


.
For more options, visit this group at
http://groups.google.com/group/liftweb?hl=en.
>>
>>

-----BEGIN PGP SIGNATURE-----


Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAkzEdfYACgkQIaMjFWMehWKixACfX2vnWZ9ZmAR7DJkSSS8B8EZQ
M5UAmQG29FPomlDiaAApZeOmds9v9vEc
=XzO/
-----END PGP SIGNATURE-----

Reply all
Reply to author
Forward
0 new messages