localStorage and logged-in user


#1

In my App user can login using website’s account.
After loggin-in I want to keep user id in localStorage. Is it safe? Can localStorage be manually changed on Android? If not how to storage data (like cookies in website)?


#2

You should assume any data on the users device is not safe so don’t just store the user id and assume it’s valid.

The most common approach to this problem is to generate a token that represents the user and store that. You would generate this token on the server and return it with the response to your login call.

It would also be best to not try and write this stuff yourself. You should be able to find a library for your server side language of choice to take care of it for you.


#3

Thanks - and what if I store user id as well as md5(password)?


#4

Don’t use MD5, it is considered broken now.

Here’s one way of going about this problem. As far as I know, it’s a safe method… There will be better ones though.

You have a database online, which for example has a username and hashed password (one that cannot be un-hashed to get the original password).

You have a server, which has some sort of API which accepts HTTP requests from somewhere, in this case your app. So for login:

http://api.com/login

The app user wants to login. They enter their username and password, and hit login. Before the request is sent, you hash that password on your app and send it off (using a GET request here):

http://api.com/login?username=bob&password=myhashedpasswordstring

Your server then checks for a match in the database. If there is no match, the response tells them they have failed. However, if there is a match we can log them in. So in the success response, we respond with the “user_id” and a unique generated token which the server API has made, using the “user_id”. Only the server knows how to create this token and what algorithm/hashing is made (using sha256, base64encode together etc), eg:

substr(base64_encode(hash_hmac('sha256', <user_id>, "MySuperSecretString")), 0, 32);

On your app you store the user_id and token in local storage.

Now lets say you have a API call which requires a valid user/login - called “data”, and we have to specify how much data we want using the “number” parameter. We can send a request like so:

http://api.com/data?number=10

But this request also requires a new “auth” parameter, which in this case is formatted like: user_id|token

Because the | (pipe) symbol needs to be url encoded, it will encoded as “%7C”, see: http://www.w3schools.com/tags/ref_urlencode.asp

Lets assume bobs user_id = “2”, and his token = “ABCDEFG” So the request will now be:

http://api.com/data?number=10&auth=2%7CABCDEFG

When this hits your server, you first need to grab the “auth” parameter. This then needs decoding, so you’d end up with (PHP syntax for example):

$auth = "2|ABCDEFG";

Now you’d explode this string using the | symbol, and now you have your user_id and given token.

To verify this is correct, you’d run the user_id through the token generator algorithm. You’d then match the result of that, with the token that was given in your “auth” parameter.

If they don’t match up, you assume that someone has tampered with either the “user_id” or “token” in the apps local storage, and thus reject the request and do whatever on the app (force logout, show an error etc).

If they do match up, then you can assume the user is genuine, and serve up the data.

Hope that helps… One way of doing it without OAuth etc.

EDIT: fixed a link


#5

I might just say again, please don’t write this stuff yourself. Find a trusted library for your server language of choice. Security is hard!

Please also realise that any token based scheme should only be used over https otherwise you are sending your auth tokens in plain text over the wire.


#6

Don’t put the token in the URL. You need to inject authorization headers into your requests. You need to look at AngularJS docs and tutorials about default headers and interceptors.


#7

@Calendee You should give him that article about security in AngularJS you posted earlier. I believe it was from Auth0?

Edit; Found it already. @Piernik read up on this:


#8

Cheers handy article. Still learning myself, just one way I thought logical to do it :smile:


#9

Is there any doc or tutorial about refresh token flow and AngularJS? I mean, the right use of http interceptors and headers to detect that token has expired and ask to API for a new one.

Thanks!


Encrypting password details
#10

Thank every one for usefull hints.


#11

Good discussion. I found this library extremely useful. I intend to write a blog post about using it with ionic.


#12

If Your write it share it here


#13

I certainly will post it here. I am planning on writing it over the weekend.


#14

Here is the article I wrote over the weekend and promised to post here:

http://www.kdmooreconsulting.com/blogs/authentication-with-ionic-and-angular-js-in-a-cordovaphonegap-mobile-web-application/


#15

can you recommend any libraries for node or php to solve this problem


#16

In this example, what is preventing someone else to sniff the local storage and make the request as the user?

For example, I can have access to the user localStorage, get his token and make a request as him, grabbing all his data instead of mine.