I have to implement login tokens in my Lithium (the PHP framework) based application. Two reasons:
I want to have a "remember me" function.
I also need a way of tracking logins on the server so that I can verify authenticated users on a node.js socket server like so:
So this is a two part question, and it's just to verify that I'm not being an idiot because the security on this site is of higher priority than usual.
Is this a reasonable way of creating a login token?
<?php
// String::hash() generates a sha512 (by default) hash.
String::hash(time() . $user['username']);
?>
Is the web socket authentication system I proposed sane? Can you see any problems arising or any more efficient ways of doing it?
Tokens Offer Robust SecuritySince tokens like JWT are stateless, only a secret key can validate it when received at a server-side application, which was used to create it. Hence they're considered the best and the most secure way of offering authentication.
Token-based authentication is a protocol that generates encrypted security tokens. It enables users to verify their identity to websites, which then generates a unique encrypted authentication token.
Tokens, such as OAuth, have way more benefits: They don't hang around. They're temporary, stored in the browser, in memory, or a protected cache. Unlike passwords or browser cookies, though, they're automatically destroyed when a session completes or exceeds the expiration time.
First, you should change the way your login token is generated. A hash of the current time concatenated with the username is far from being difficult to guess; which is a necessary condition for it to be secure. There are many ways to do this, what's crucial is that you use a good source of randomness. You could do:
list(,$token) = unpack('H*', openssl_random_pseudo_bytes(15, $safe));
$safe or die("unsafe source");
The overall method you're using is only secure if you the bearer token you're passing around is never sent unencrypted. This means every time it is transmitted it must be transmitted over SSL/TLS.
There's still the problem that you may accidentally send the token to the wrong place, so you must be extra careful if any destination is somehow dynamically generated (e.g. through some discovery protocol). The only way to avoid this problem would be to use cryptography.
You should look at the RequestToken
class in Lithium: http://li3.me/docs/lithium/security/validation/RequestToken::check()#source
It handles CSRF protection, and uses cryptographically secure random tokens, based on principles similar to the above, but with an extra layer of protection with bcrypt, which can match any number of unique hashes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With