jsonwebtoken/README.md

160 lines
5.1 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/)
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
## 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};
use jsonwebtoken::{encode, decode, Header, Algorithm, Validation};
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
2017-09-08 02:36:52 -04:00
The default algorithm is HS256.
2015-11-02 16:04:58 -05:00
```rust
2017-08-25 04:53:32 -04:00
let token = encode(&Header::default(), &my_claims, "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());
let token = encode(&header, &my_claims, "secret".as_ref())?;
```
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
let token = encode(&Header::default(), &my_claims, "secret".as_ref())?;
// 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
- a key
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
let token = decode::<Claims>(&token, "secret".as_ref(), &Validation::default())?;
2019-11-14 13:43:43 -05:00
// token is a struct with 2 fields: `header` and `claims` and `claims` is your own struct.
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.
In some cases, for example if you don't know the algorithm used or need to grab the `kid`, you can decode only the header:
2017-08-25 04:53:32 -04:00
```rust
let header = decode_header(&token)?;
```
2019-11-14 13:43:43 -05:00
This does not perform any signature verification/validations on the token so it could have been tampered with.
You can also decode a token using the public key components of a RSA key in base64 format.
The main use-case is for JWK where your public key is a JSON format like so:
```json
{
"kty":"RSA",
"e":"AQAB",
"kid":"6a7a119f-0876-4f7e-8d0f-bf3ea1391dd8",
"n":"yRE6rHuNR0QbHO3H3Kt2pOKGVhQqGZXInOduQNxXzuKlvQTLUTv4l4sggh5_CYYi_cvI-SXVT9kPWSKXxJXBXd_4LkvcPuUakBoAkfh-eiFVMh2VrUyWyj3MFl0HTVF9KwRXLAcwkREiS3npThHRyIxuy0ZMeZfxVL5arMhw1SRELB8HoGfG_AtH89BIE9jDBHZ9dLelK9a184zAf8LwoPLxvJb3Il5nncqPcSfKDDodMFBIMc4lQzDKL5gvmiXLXB1AGLm8KBjfE8s3L5xqi-yUod-j8MtvIj812dkS4QMiRVN_by2h3ZY8LYVGrqZXZTcgn2ujn8uKjXLZVD5TdQ"
}
```
```rust
let token = decode_rsa_components::<Claims>(&token, jwk["n"], jwk["e"], &Validation::new(Algorithm::RS256))?;
// token is a struct with 2 fields: `header` and `claims` and `claims` is your own struct.
```
### Convertion .der to .pem
You can use openssl for that:
```bash
openssl rsa -inform DER -outform PEM -in mykey.der -out mykey.pem
```
2017-09-08 02:36:52 -04:00
#### Validation
This library validates automatically the `exp` claim. `nbf` is also 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
```
2015-11-02 16:04:58 -05:00
## Algorithms
2017-04-12 21:29:30 -04:00
This library currently supports the following:
- HS256
- HS384
- HS512
- RS256
- RS384
- RS512
- PS256
- PS384
- PS512
2019-03-22 04:40:08 -04:00
- ES256
- ES384
2017-04-14 05:15:06 -04:00
2019-11-14 13:43:43 -05:00
### RSA & ECDSA
By default, the `encode`/`decode` functions takes the PEM format since it is the most common.
RSA can also use the public key components modulus/exponent in base64 format for decoding.