jsonwebtoken/README.md

171 lines
5.5 KiB
Markdown
Raw Normal View History

2015-11-02 18:27:28 -05:00
# jsonwebtoken
2015-10-31 11:37:15 -04:00
2017-04-26 03:51:44 -04:00
[![Build Status](https://travis-ci.org/Keats/jsonwebtoken.svg)](https://travis-ci.org/Keats/jsonwebtoken)
2015-11-02 16:04:58 -05:00
2017-04-23 01:27:19 -04:00
[API documentation on docs.rs](https://docs.rs/jsonwebtoken/)
2019-11-15 14:33:49 -05:00
See [JSON Web Tokens](https://en.wikipedia.org/wiki/JSON_Web_Token) for more information on what JSON Web Tokens are.
2019-11-14 14:24:38 -05:00
2015-11-02 18:27:28 -05:00
## Installation
Add the following to Cargo.toml:
```toml
2019-06-16 11:51:43 -04:00
jsonwebtoken = "7"
2019-11-14 13:43:43 -05:00
serde = {version = "1.0", features = ["derive"] }
2015-11-02 18:27:28 -05:00
```
2015-11-02 16:04:58 -05:00
2019-11-14 14:35:20 -05:00
The minimum required Rust version is 1.36.
2019-11-14 14:24:38 -05:00
## Algorithms
This library currently supports the following:
- HS256
- HS384
- HS512
- RS256
- RS384
- RS512
- PS256
- PS384
- PS512
- ES256
- ES384
2015-11-02 16:04:58 -05:00
## How to use
2017-09-08 02:36:52 -04:00
Complete examples are available in the examples directory: a basic one and one with a custom header.
2015-11-02 16:04:58 -05:00
2017-09-08 02:36:52 -04:00
In terms of imports and structs:
2015-11-02 18:32:32 -05:00
```rust
2019-11-14 13:43:43 -05:00
use serde::{Serialize, Deserialize};
2019-12-29 12:42:35 -05:00
use jsonwebtoken::{encode, decode, Header, Algorithm, Validation, EncodingKey};
2015-11-02 18:32:32 -05:00
2017-09-08 02:36:52 -04:00
/// Our claims struct, it needs to derive `Serialize` and/or `Deserialize`
#[derive(Debug, Serialize, Deserialize)]
struct Claims {
sub: String,
2018-10-28 14:54:35 -04:00
company: String,
exp: usize,
2017-09-08 02:36:52 -04:00
}
```
2015-12-22 12:17:53 -05:00
2019-11-14 13:43:43 -05:00
### Header
2019-11-14 14:24:38 -05:00
The default algorithm is HS256, which uses a shared secret.
2017-09-08 02:36:52 -04:00
2015-11-02 16:04:58 -05:00
```rust
2019-12-29 12:42:35 -05:00
let token = encode(&Header::default(), &my_claims, &EncodingKey::from_secret("secret".as_ref()))?;
2015-11-02 16:04:58 -05:00
```
2017-09-08 02:36:52 -04:00
#### Custom headers & changing algorithm
All the parameters from the RFC are supported but the default header only has `typ` and `alg` set.
If you want to set the `kid` parameter or change the algorithm for example:
```rust
2019-11-14 13:43:43 -05:00
let mut header = Header::new(Algorithm::HS512);
2017-09-08 02:36:52 -04:00
header.kid = Some("blabla".to_owned());
2019-12-29 12:42:35 -05:00
let token = encode(&header, &my_claims, &EncodingKey::from_secret("secret".as_ref()))?;
2017-09-08 02:36:52 -04:00
```
Look at `examples/custom_header.rs` for a full working example.
2015-11-02 16:04:58 -05:00
2019-11-14 13:43:43 -05:00
### Encoding
```rust
// HS256
2019-12-29 12:42:35 -05:00
let token = encode(&Header::default(), &my_claims, &EncodingKey::from_secret("secret".as_ref()))?;
2019-11-14 13:43:43 -05:00
// RSA
let token = encode(&Header::new(Algorithm::RS256), &my_claims, include_str!("privkey.pem"))?;
```
Encoding a JWT takes 3 parameters:
- a header: the `Header` struct
- some claims: your own struct
2019-11-14 14:24:38 -05:00
- a key/secret
2019-11-14 13:43:43 -05:00
When using HS256, HS2384 or HS512, the key is always a shared secret like in the example above. When using
RSA/EC, the key should always be the content of the private key in the PEM format.
2015-11-02 16:04:58 -05:00
### Decoding
2019-11-14 13:43:43 -05:00
2015-11-02 16:04:58 -05:00
```rust
2019-11-14 14:24:38 -05:00
// `token` is a struct with 2 fields: `header` and `claims` where `claims` is your own struct.
let token = decode::<Claims>(&token, "secret".as_ref(), &Validation::default())?;
2015-11-02 16:04:58 -05:00
```
2017-04-12 21:29:30 -04:00
`decode` can error for a variety of reasons:
2015-11-02 16:04:58 -05:00
2017-04-12 21:29:30 -04:00
- the token or its signature is invalid
2019-11-14 13:43:43 -05:00
- the token had invalid base64
2017-04-13 03:36:32 -04:00
- validation of at least one reserved claim failed
2015-11-02 16:04:58 -05:00
2019-11-14 13:43:43 -05:00
As with encoding, when using HS256, HS2384 or HS512, the key is always a shared secret like in the example above. When using
RSA/EC, the key should always be the content of the public key in the PEM format.
2019-11-14 14:24:38 -05:00
In some cases, for example if you don't know the algorithm used or need to grab the `kid`, you can choose to decode only the header:
2017-08-25 04:53:32 -04:00
```rust
let header = decode_header(&token)?;
```
2019-11-14 14:24:38 -05:00
This does not perform any signature verification or validate the token claims.
2019-11-14 13:43:43 -05:00
You can also decode a token using the public key components of a RSA key in base64 format.
2019-11-14 14:24:38 -05:00
The main use-case is for JWK where your public key is in a JSON format like so:
2019-11-14 13:43:43 -05:00
```json
{
"kty":"RSA",
"e":"AQAB",
"kid":"6a7a119f-0876-4f7e-8d0f-bf3ea1391dd8",
"n":"yRE6rHuNR0QbHO3H3Kt2pOKGVhQqGZXInOduQNxXzuKlvQTLUTv4l4sggh5_CYYi_cvI-SXVT9kPWSKXxJXBXd_4LkvcPuUakBoAkfh-eiFVMh2VrUyWyj3MFl0HTVF9KwRXLAcwkREiS3npThHRyIxuy0ZMeZfxVL5arMhw1SRELB8HoGfG_AtH89BIE9jDBHZ9dLelK9a184zAf8LwoPLxvJb3Il5nncqPcSfKDDodMFBIMc4lQzDKL5gvmiXLXB1AGLm8KBjfE8s3L5xqi-yUod-j8MtvIj812dkS4QMiRVN_by2h3ZY8LYVGrqZXZTcgn2ujn8uKjXLZVD5TdQ"
}
```
```rust
2019-11-14 14:24:38 -05:00
// `token` is a struct with 2 fields: `header` and `claims` where `claims` is your own struct.
2019-11-14 13:43:43 -05:00
let token = decode_rsa_components::<Claims>(&token, jwk["n"], jwk["e"], &Validation::new(Algorithm::RS256))?;
```
2019-11-14 14:24:38 -05:00
### Converting .der to .pem
2019-11-14 13:43:43 -05:00
You can use openssl for that:
```bash
openssl rsa -inform DER -outform PEM -in mykey.der -out mykey.pem
```
### Convert SEC1 private key to PKCS8
`jsonwebtoken` currently only supports PKCS8 format for private EC keys. If your key has `BEGIN EC PRIVATE KEY` at the top,
this is a SEC1 type and can be converted to PKCS8 like so:
```bash
openssl pkcs8 -topk8 -nocrypt -in sec1.pem -out pkcs8.pem
```
2017-09-08 02:36:52 -04:00
2019-11-14 14:24:38 -05:00
## Validation
This library validates automatically the `exp` claim and `nbf` is validated if present. You can also validate the `sub`, `iss` and `aud` but
2017-09-08 02:36:52 -04:00
those require setting the expected value in the `Validation` struct.
Since validating time fields is always a bit tricky due to clock skew,
2019-11-14 13:43:43 -05:00
you can add some leeway to the `iat`, `exp` and `nbf` validation by setting the `leeway` field.
2017-09-08 02:36:52 -04:00
2017-10-22 07:20:01 -04:00
Last but not least, you will need to set the algorithm(s) allowed for this token if you are not using `HS256`.
2017-04-12 21:29:30 -04:00
```rust
2017-04-22 02:21:16 -04:00
use jsonwebtoken::{Validation, Algorithm};
2017-04-12 21:29:30 -04:00
2017-11-14 11:18:25 -05:00
// Default validation: the only algo allowed is HS256
2017-04-12 21:29:30 -04:00
let validation = Validation::default();
2017-10-22 07:20:01 -04:00
// Quick way to setup a validation where only the algorithm changes
let validation = Validation::new(Algorithm::HS512);
// Adding some leeway (in seconds) for exp and nbf checks
2017-08-30 05:09:57 -04:00
let mut validation = Validation {leeway: 60, ..Default::default()};
2017-04-12 21:29:30 -04:00
// Checking issuer
let mut validation = Validation {iss: Some("issuer".to_string()), ..Default::default()};
// Setting audience
let mut validation = Validation::default();
validation.set_audience(&"Me"); // string
validation.set_audience(&["Me", "You"]); // array of strings
```
2019-11-14 14:32:03 -05:00
Look at `examples/validation.rs` for a full working example.