I think I have this sorted, but would love to hear if I'm wrong. We have a Python+Angular.js set of apps, which are using JWT tokens for authentication, where the tokens are encrypted using a secret key, the payload identifies the user, and the token is stored client side in a cookie set as HTTP ONLY and as secure. For a variety of reasons this works well for us, we get to use one Python wsgi middleware app across multiple API backends, our token gets sent automatically on every request to the domain, and we get to bypass using sessions entirely. I've had this part checked out on here and elsewhere and I'm confident it's good. ( my question on that is here: http_only for cookies with JWT tokens )
My new question is how to handle CSRF tokens, given that we are not using sessions at all. I am thinking the following:
- auth is handled off the jwt token in the cookie described above, let's call it accept_token_cookie. JS can't read it, it's HTTP ONLY. Has the user id.
- a second cookie is sent with our CSRF token, which is not HTTP_ONLY, thus angular can read it (let's call it csrf_cookie)
- csrf_cookies payload is an encryption of our identity payload (or part of it, like user email), but made with a second secret key
- when an XHR request is made, my JS will look at the csrf_cookie value, and add it to a header
- on ingress, our server decodes both cookies and gets the token as sent by angular in a custom header. If these do not all match, we know this request is bad because the requesting javascript couldn't read our csrf_cookie. However, csrf_cookie is still not used at all to generate identity, which is what we want so that the accept_token cookie remains totally opaque to the client.
From all my reading, the above sounds correct. If I'm wrong, please tell me why, thanks.