Vidarlo's answer is mostly right, but, incidentally, there was one fatal flaw in the protocol: the protocol was intentionally designed to allow replays to some degree. In particular, it was designed to allow retransmissions of message 3 in the handshake to succeed. But who's to say that it's the original client retransmitting the frame instead of an attacker? As it turns out, no one. This is the basis for the KRACK attack which was indeed a successful replay attack against WPA2.
While KRACK (Key Reinstallation AttaCK) didn't directly allow spoofing a Wi-Fi client, it could be used to repeatedly reset the nonce and the replay counter, which caused future frames to be encrypted with nonces that had already been used, which could in turn allow the attacker to slowly discover key material.
Interestingly, despite being a fundamental problem in the 4-way handshake itself, knowledge of this vulnerability wasn't publicly disclosed until late 2017.
US-CERT described the attack this way (emphasis mine):
US-CERT has become aware of several key management vulnerabilities in the 4-way handshake of the Wi-Fi Protected Access II (WPA2) security protocol. The impact of exploiting these vulnerabilities includes decryption, packet replay, TCP connection hijacking, HTTP content injection, and others. Note that as protocol-level issues, most or all correct implementations of the standard will be affected. The CERT/CC and the reporting researcher KU Leuven, will be publicly disclosing these vulnerabilities on 16 October 2017.
If you want to read about the details of how the attack worked, the original paper by the researchers who discovered it is an interesting read.
Interestingly (and kind of amusingly,) the attack didn't affect the 4-way handshake in Windows and iOS because the Wi-Fi stack in those operating systems did not implement WPA strictly according to the 802.11 standard. In particular, they did not allow message 3 of the 4-way handshake to be replayed (which the standard requires to be allowed,) which defeated the attack. I'm not sure whether this invulnerability was due to a smart engineer noticing that the standard was poorly-designed on this point or a lazy engineer not implementing the state machine to allow replays of message 3, but, either way, it worked out for the best. However, their implementations of the group handshake (the one for negotiating keys for broadcasting messages to all connected stations) were still vulnerable to the attack.