6

I am developing a Restful Web Service using Jersey between my Android, iPhone apps and MySQL. I also use Hibernate to map the data to the database.

I have a sessionId (key). it is generated when user Login to the system.

In User class:

public Session daoCreateSession() {
    if (session == null) {
        session = new Session(this);
    } else {
        session.daoUpdate();
    }
    return session;
}

In Session Class:

Session(User user) {
    this.key = UUID.randomUUID().toString();
    this.user = user;
    this.date = new Date();
}

void daoUpdate() {
    this.key = UUID.randomUUID().toString();
    this.date = new Date();
}

When user Sign in to the system successfully, I send this sessionId to the Mobile app client. Then when I want to get some information from database based on the logged in user, I check this Session key as authentication in the REST Services for every request.

For example for the list of project that user is involved in, I use client.GET(SERVER_ADDRESS/project/get/{SessionID})

insetead of client.GET(SERVER_ADDRESS/project/get/{username}).

And if it is not a valid session key, I'll send back to the client a 403 forbidden code. You can also take a look here

The thing is I am not sure about my approach. what do you think about cons in this approach considering for Jersey and a mobile app? I still don't know if the Session key approach is a good idea in my case.

Ali
  • 9,800
  • 19
  • 72
  • 152
  • This is not RESTful. The `SessionID` will change so your URLs will *not* reference Resources. –  Sep 03 '12 at 09:59
  • Why?I just use [this approach](http://jersey.576304.n2.nabble.com/Security-Basic-Session-or-Encrypted-Key-td3490249.html) – Ali Sep 03 '12 at 10:03
  • An URL identifies a Resources. What are your resources? –  Sep 03 '12 at 10:04
  • No, MySQL is your backend. In your context, projects and users are Resources. Please read a [brief introduction to REST](http://www.infoq.com/articles/rest-introduction). –  Sep 03 '12 at 10:08
  • Ok, thanks, you are right,but you already knew the answer of your question :) – Ali Sep 03 '12 at 10:10
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/16186/discussion-between-ali-and-tichodroma) – Ali Sep 03 '12 at 10:17

2 Answers2

6

If you want to use SessionId then it should have a validation time, like this:

private static final int MINUTES = 90;

public boolean isValid() {
   return System.currentTimeMillis() - date.getTime() < 1000 * 60 * MINUTES;
}
Ali
  • 9,800
  • 19
  • 72
  • 152
Nooshin
  • 178
  • 2
  • 9
4

This is a solved problem - servlet containers like Tomcat already do session management, and can distribute session state to other containers in the cluster either by broadcasting over TCP, or by using a shared data source like memcache.

I'd suggest reading up on what's already available, rather than inadvertently reinventing the wheel. Additionally, this is going to become an incredibly hot table table if your application proves popular. How will you clear out old session IDs?

DeejUK
  • 12,891
  • 19
  • 89
  • 169
  • Every time that user login to the system, a new session Id will be generated.also this is a temporary Id, it becomes expired after a while. – Ali Sep 03 '12 at 10:36
  • Having every request requiring an operation on the same table would be bad if you're expecting high load. Every login requires a write, every other operation requires a read on a large table that wouldn't be indexed efficiently (UUIDs are bad for that), and then you'll need a background thread to scan over the table and delete expired session IDs, else the table will fill up with useless data. I'd really urge you to look at using Tomcat's inbuilt session management backed by http://code.google.com/p/memcached-session-manager – DeejUK Sep 03 '12 at 10:43
  • He's actually creating a token system for sessionless requests. – Brill Pappin Feb 18 '15 at 19:15