- rate limiting
- cryptographically secure tokens (not rand() or guid())
- expire sessions
- sanitize for xss
- validate ownership of email
- normalize case sensitivity
- unique per user / per application salt with hash (bcrypt / scrypt... but maybe not)
- break up data (one store for salt, one for hash, one (app config?) for iterations)
- !password restore
- reset tokens are one-use and expire fast
- Apache Shiro Framework (authentication)
- 2 factor
- last login time / geo info