I'd argue that UUIDv4 is not strong enough for conformance with some standards.
For example, RFC6819, OAuth 2.0 Threat Model and Security Considerations requires:
When creating secrets not intended for usage by human users (e.g.,
client secrets or token handles), the authorization server should
include a reasonable level of entropy in order to mitigate the risk
of guessing attacks. The token value should be >=128 bits long and
constructed from a cryptographically strong random or pseudo-random
number sequence (see [RFC4086] for best current practice) generated
by the authorization server.
Strictly speaking, UUIv4 is “>=128 bits long” but I think the intent is actually to say that the token should have at least 128 bit of entropy. UUIDv4 only has 122 bits of entropy.
RFC6747, The OAuth 2.0 Authorization Framework says:
The probability of an attacker guessing generated tokens (and other
credentials not intended for handling by end-users) MUST be less than
or equal to 2^(-128) and SHOULD be less than or equal to 2^(-160).
which I believe is supposed to mean that the tokens for Oauth MUST have at least 128 bits of entropy and SHOULD have at least 160 bits of entropy.
Note that many OAuth implementations actually use UUIDv4 tokens in practice.
If you want to generate a random password/token, I'd suggest something like (example in Node.js):
https secure context only):
// 1. Unsigned 8-bit integer array with a length of 20, equivalent to 160 bits.
const array = new Uint8Array(160 / 8);
// 2. Fill the array with cryptographically strong random values.
// 3. Convert the array into a base64 string.
const base64String = btoa(String.fromCharCode(...array));
// 4. Convert the base64 string into a base64 url safe string.
const base64StringUrlEncoded = base64String
// 5. Output `token`
RFC 4648 - Section 5 - Base 64 Encoding with URL and Filename Safe Alphabet
You can easily adjust the number of bits of entropy and your token is more compact (in term of bits of entropy per byte) that a standard UUIDv4 representation.