5

So i am creating my first larger scale application (by larger scale i mean something i see myself publishing in the app store) and i am not sure of how to handle user authorization. The client will consist of a application for android and iphone, and they make HTTP requests on a server.

My data is stored in a postgreSQL server and i have already implemented so that a user can log in, but right now logging in basically means nothing. When you query the database there is no check to make sure that the data you request / wish to alter is yours.

I was thinking that when a user log in they receive a token. Whenever a request would be made upon a user ID, the host requesting this data would also have to provide that IDs token.

Queries are made with rest calls, and are usually of the form [id of user, new data 1, new data 2, new data 3], and this new data will be inserted into a table, and the new row will have a relation to the client id.

The data i store is in no way sensitive. Most requests will be a user wishing to add a row to a table in my database. The most sensitive piece of information would probably be a users email, so this authentication system would only be in place to ensure that no one is inserting troll-data on a client that is not them.

Another point i'm not sure how to handle is what to do when the token expire. I cannot request the user to log in every few hours, the token should be renewed automatically. Is it normal to store id / pass at the client and do the request automatically?

  • You can store just the token. Next time user send you the token check it. If it's expired let it pass, but return back the new one. The new one can be informed vía http response headers. If your client detect a new token, just replace the one storedby the new one. And so on... This approach require to persist 2 tokens. The expired is removed after being dispatched the newest – Laiv Jun 1 '16 at 21:08
  • No need to say that, if there's no new token for that user, then don't let it pass. This case means that user is no longer user of.your system, but some how it kept its last token and is trying to get accesss – Laiv Jun 1 '16 at 21:15
  • @Laiv I had recommended the approach you describe in my answer but then I realized that if an attacker is able to capture a currently valid token, they will be able to login indefinitely as long as they keep renewing. – JimmyJames Jun 2 '16 at 16:25
  • You are right. Plus token could be stolen and user wouldn't be able to recover its account. If its last token expired and it was removed from db. Unless he relogged vía credentials. That would force token refresh and it would recover its account – Laiv Jun 2 '16 at 16:36
  • Have a look OAuth 2, which is an open standard for authorization. It also describes "flows" that implements such a token-based solution – haraldK Jun 2 '16 at 17:14
2

First off, the token approach seems sound for your case. One option is to encrypt user information (e.g. id) into the token. On the server side, you can then keep things stateless. Realize that no matter the details of how it is generated, this token is sensitive. If someone has it, they can use it to pretend to be that user as long as it is valid (just like a session id.)

To the last part, it's unclear what the log in requirement is here. You say you don't want them to have to log in every few hours. How often do you want them to have to log in and is that based on inactivity? I would not recommend storing the credentials as other applications on the device could potentially retrieve the credentials.

1

Don't really know the full use case but this really screams using a session to me. Normally these are implemented with a unique ID sent to the client in the form of a cookie and stored on the server in an in memory database like redis or memcached.

When a user logs a new object will be added to redis and stored by a unique key with any user information needed, an expire time can be set here too. Setting an expiry will automatically remove a key from the cache which will make a user's session invalid if it is past the expire date. For your case it would probably store just the user id, it could also be used to store any other commonly used static data that doesn't need to be queried every time.

Since session information is useful on most endpoints a top level filter is normally implemented to query redis for the key and store the user information on the request before any handler logic is executed. If the key does not exist a 403 status could be sent in the response.

It all depends on what server side technology you are using but this pattern is very common and could already be implemented in the framework you are using. For example I wrote up some pseudoish code in a few minutes that uses express and their redis session object. Just with a few lines of code it provides session expiry support and user data security.

    var session = require('express-session');
var RedisStore = require('connect-redis')(session);

//this is middleware provided by the library which will query `redis`
// from the request cookie, add the session to the request data and
//update the expiry with user activity.
app.use(session({
    store: new RedisStore({ttl: 10000000}),
    secret: 'keyboard cat'
}));

app.post('login', function(req, resp) {
    var sessionData = doLogin(req);
    //store the session data on the request if login is successful
    if(sessionData) {
        req.session = sessionData;
    }

    resp.send(200);
});

app.post('insert', function(req, resp) {
     var userId = req.session && req.session.userId;
     // use the session data to validate the user
     if(userId) {
        doInsert(req);
        resp.send(200);
     }
     else {
        resp.send(403);
     }
}); 

Just a side note, normally an api shouldn't take the user as a param to manipulate data for a that user because it is very prone to hacking. Storing the user information on a session and always referencing the user information will prevent any unauthorized user data manipulation.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.