raw4j
raw4j copied to clipboard
Retain session and make it portable across instances (Android compatibility)
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.
I actually started working on this a little bit before you opened your ticket.
It should always have an issue for the records.
The following commit adds support for viewing messages from inbox (limited) and sessions. https://github.com/genericjay/raw4j/commit/55a52b09c0e6063b9dab34063f15e58986e3afa6
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 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).
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.
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.
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.
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?)
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.