raw4j icon indicating copy to clipboard operation
raw4j copied to clipboard

Retain session and make it portable across instances (Android compatibility)

Open abonander opened this issue 12 years ago • 10 comments

Currently, RAW4J does not retain session, which means that it needs a call to Reddit.login() for every instance of the class before any action can be taken. This can lead to a lot of superfluous requests.

The API returns a reddit_session cookie which should be passed in later requests. There is a system-wide cookie handler that should be holding onto this, but it may or may not get destroyed at an arbitrary time by the system.

Different components in an Android application cannot share instances of a class unless it is a singleton.

The session cookie should be accessible as a String which can then be passed to different Reddit instances, perhaps with a restoreSession(String) method.

abonander avatar Oct 04 '13 01:10 abonander

I actually started working on this a little bit before you opened your ticket.

jjestrel avatar Oct 04 '13 01:10 jjestrel

It should always have an issue for the records.

abonander avatar Oct 04 '13 01:10 abonander

The following commit adds support for viewing messages from inbox (limited) and sessions. https://github.com/genericjay/raw4j/commit/55a52b09c0e6063b9dab34063f15e58986e3afa6

jjestrel avatar Oct 04 '13 02:10 jjestrel

I was actually working on the comment call last night and kept getting USER_REQUIRED error from the Reddit API. I was trying to pass in a modhash retrieved from logging in as an URL encoded form parameter as well as the X-Modhash header which seems to be preferred.

It appears as if I misinterpreted the API docs, and that the reddit_cookie is used to authenticate between each call as opposed to the modhash? Or is the modhash used for something else entirely?

genericyjay - So if your commit addresses this issue, please submit a pull request so we can see the Travis CI build results.

corydissinger avatar Oct 04 '13 12:10 corydissinger

@corydissinger The modhash, according to the API docs, is just a secondary verification to prevent CSRF (cross-site request forgery) attacks, which happen after the user is authenticated. It is there to make sure that the user was the one who submitted the request, and not a hidden script on the third-party page they just accessed. The Wikipedia article explains it pretty clearly.

Basically, since the modhash is sent in the HTTP response header, it isn't retained by the browser, unlike the session cookie, which the browser would send (with all good intentions) in a request initiated by a CSRF attack. The modhash is accessible by the caller only, since they were (or should have been) the only one to get it, so only the caller can retain the modhash to use it to verify the legitimacy of their next request.

The reddit_cookie is the actual session cookie that lets the user (or their browser, more specifically) keep making calls on their account without complete reauthentication (i.e. with username and password).

abonander avatar Oct 06 '13 11:10 abonander

Could @genericjay's solution not be improved by making the session static? That way it's retained across multiple Reddit instances without having to pass the session to each new Reddit instance in a constructor.

JamesGold23 avatar Jun 11 '14 00:06 JamesGold23

I'm curious to know why you would need multiple Reddit instances in the first place?

Admittedly it's been a while since I've worked on raw4j myself, but the Reddit class and the underlying RedditRequestor making HTTP calls is thread-safe. executeGet and executePost don't modify any instance level variables. The only problem that could arise is if you are calling setSession between requests - then you could end up changing the Cookie just before you make an API call.

Then again, due to the rate-limiting nature (30 requests per minute maximum) being able to make many requests simultaneously could be a moot point.

corydissinger avatar Jun 11 '14 00:06 corydissinger

In the OP, @cybergeek94 made it sound like it's useful to have multiple instances in Android applications, although I've never done any Android dev myself.

JamesGold23 avatar Jun 11 '14 00:06 JamesGold23

Ah, we never really addressed @cybergeek94 concern.

I've done a bit of Android development, and IMO I'm not quite sure why you would want multiple Reddit instances in a single app. You would definitely want all the work done by the Reddit class to happen in it's own thread, so something like a Service would probably be a good candidate for containing it. Maybe a full-blown service is a bit heavyweight, but I can't see the need for multiple instances (unless you want each one to maintain it's own session?)

corydissinger avatar Jun 11 '14 01:06 corydissinger

That sort of ties into a feature I was thinking about: having multiple users logged in to the same Reddit instance at once so you can switch between them at any point. Or at least some user-switching functionality; I'm not quite sure how raw4j handles that now. Perhaps you can just call login() again with a different username/password to switch.

JamesGold23 avatar Jun 11 '14 01:06 JamesGold23