Reputation: 79168
I am looking at the examples of JWT tokens in Node.js, and the verify
function. My question is, where does this publicKey
come from in verify(token, publicKey)
? What is the flow?
The client (one of my users) has a client library installed on their computer/server, for making requests to my app myapp.com
. In the myapp.com
server, I call verify(token, publicKey)
. In the client library I generate the token using privateKey
. The question is, how does the client get this private key generally? (i.e. is heroku login
downloading a private key under the hood for making JWT requests, sort of thing?). And how do you fetch the public key? My understanding is, the client would download a private key, and our server would store the public key. Then given you have the public key and token, just call verify(token, publicKey)
. But how do you get the public key for the token on the server generally? Is the server storing one public key per private key disseminated to the client installed libraries?
Upvotes: 5
Views: 6612
Reputation: 4033
The way I've usually seen JWTs used, there is only a very small number of trusted issuers, often only one, and the tokens are used as bearer tokens. In many cases, the issuer and the verifier are the same. In other cases, the verifier trusts one identity provider (e.g. Google) and fetches the public key from a https URL (example).
In your case, you could act as both the issuer and verifier:
This is e.g. the approach described here as the approach used by GitHub. In this case, the issuer and verifier both belong to you. This approach is the easiest for both you (you can trust the content of the JWTs once you've verified the signature), and the client (they're just dealing with an opaque API key and don't need to deal with the complexities of JWTs at all).
A possible alternative approach could be:
iss
and or sub
field).This approach is used e.g. by Google Cloud for service account authentication.
Step 1 above can be done in two ways:
Either way, if you go with the "user signs a JWT" approach, you likely will want to provide client libraries, or at least code examples. Note also Google's requirement that the tokens must be short-lived, enforced by treating long-lived tokens as invalid. Without this rule and enforcement, what will happen is that many client developers will be annoyed about your complicated solution, manually sign a token that is valid forever on his laptop, and then use it as a bearer token.
heroku login
actually doesn't use JWTs at all. It retrieves and stores an OAuth Bearer Token. This is most comparable to the first approach (client never handles any private keys, just gets an opaque blob, which happens to be a JWT that you can verify). The difference between a non-JWT token and a long-lived JWT is that your API servers have to look up the meaning and validity of the regular token in a database, whereas the JWT directly tells you the user identity, and possibly permissions and other attributes that you included when issuing it.
Upvotes: 7