I disagree about using cookies instead of localStorage. Cookies with the HttpOnly flag enabled (as suggested in the article) don't work well in some environments such as hybrid HTML5/native apps (using WebViews) because of cross-origin restrictions - For an app which runs inside a WebView, the cookie will not be sent to the server if your script files are served from the mobile devices' file system - So your server will never get the JWT token in this case. With localStorage (or a Cookie WITHOUT HttpOnly), you can manually read the JWT using JavaScript and send it through - I know this opens you up to XSS attacks but it's a small price to pay.
Most frontend developers accept the fact that if you have malicious third-party code running inside your app's frontend, that's pretty bad news in any case. The fact that the malicious code can access a user's JWT token isn't the worst thing that could happen - At that point, the malicious frontend code could theoretically do anything it wants with your account by hijacking your UI.
The simple solution to mitigate XSS attacks is to serve all your frontend scripts from your own trusted CDNs - When it comes to vulnerabilities, there is always a tradeoff between CSRF and XSS - Personally, I find XSS threats much easier to manage than CSRF (it's a smaller attack surface).
Also, you CAN invalidate JWT tokens - You can change the auth key from the server-side (thereby invalidating the signature of previously issued tokens). Or you can send JWTs with really short expiries (e.g. every 10 minutes) and then renew them on an interval (e.g. every 9 minutes) so that the JWT doesn't expire while the user is still active.
There are a lot of different ways to use JWTs safely. It is not right for someone to say that a technology is bad unless they are aware of all the possible use cases for it.