I could have users request a token every rest call and store them within the class and not within the custom setting
You can take the advantages of both approaches. Set up your callout so you can use a token from within memory. If you need to update your setting, move that DML to the end of your transaction.
Pseudo-code:
String token = MySetting__c.getOrgDefaults__cgetOrgDefaults().Token__c;
// if the token is blank or expired, get a new one
// and reassign the value in your token variable
// make your callout using the valid token
// if the token was blank or expired, update your setting