Avoid allowing email spam. Rate limit the emails sent so that an attacker cannot spam your users by submitting the forgot password form multiple times.
When creating a reset token, ensure that it has good entropy so that it can't be guessed. Don't just create a token based on the time and the user ID because that can be guessed and brute forced too easily, as it lacks enough entropy. You should use at least 16-32 random bytes for a token to have decent entropy. Refer to Chapter 6, Cryptography, for examples of generating cryptographically secure random bytes.
Also, set the token to expire after a short period. Anywhere from one hour to one day are good options depending on your application. Only allow one reset token ...