Thanks for the write up. It saved me a ton of time and explained a lot.
Just in case any one is using ngrok instead of localhost and getting oauth permissions issues. When building the permission url, you need to call Flask’s url_for with the _scheme parameter. Without that, it kept returning http for me and guessing it has something to do with the ngrok proxy server to localhost. Anyway, just updated the code to this and it worked: