How is Phoenix.Token different from JWT?

After some digging, I’ve found the following sources of information: the issue (#699) about token auth, the corresponding PR (#820), and the Phoenix.Token documentation itself. I’m writing this mainly as a note for myself, hoping for some clarification, and I figured it might help someone along the way.

Based on the issue, the motivation of the Phoenix.Token module itself is the need to have a general API for generating tokens to be used for channel and API authentication. It doesn’t actually dictate how the implementation itself works. The issue specifically discussed about how the API would look like and, consequently, how it would be implemented.

There were two options for the implementation, one using Plug Tokens (through Plug.Crypto) and the other JWT. The discussion kind of ended abruptly (possibly because a more thorough brainstorming was conducted somewhere else) stating that the chosen approach is the Plug one. I inferred that one of the reasons might be that by using Plug Tokens there’s no need to add another dependency and it works for most cases.

So, to answer the question: Phoenix.Token (with Plug Tokens) vs. JWT, several points I noticed:

  1. Phoenix.Token doesn’t let you specify signing algorithms (defaulting to sha256 according to this line on MessageVerifier). JWT (for example using Joken) does.

  2. Both encodes some form of payload into Base64, and the encoding can be read by clients (so you shouldn’t include sensitive information).

  3. JWT allows you to encode arbitrary JSON objects as payload, Phoenix.Token uses Erlang terms serialization so you can’t really do that (I’m not sure I fully understand this one, see this rejected PR for details). That said, the docs doesn’t really tell you what kind of data you can use as payload; I’m not sure everyone is familiar what Erlang terms are.

Other than that, I think the token generated using Phoenix.Token and JWT behaves the same.

A question that still bugs my mind is about the salt parameter. The docs doesn’t really specify whether you should use hardcoded strings like "user" (and commit it to version control) or should we use randomized secrets strings for that, and how it will affect the tokens. I’d be happy to put up some PRs for the docs but as of now I don’t think I have the sufficient knowledge for that.

16 Likes