After the signature validation executes, the result contains the parsed JWT claims from the JWT token.
In case the signature is invalid or you choose not to validate the signature, PDK provides the JWTClaimsParser to parse claims. This structure provides a parse method that returns Result<JWTClaims, JWTError>.
// Being "token" a String that contains a JWT token
let parsed_claims = JWTClaimsParser::parse(token);
if claims.is_err() {
return Flow::Break(Response::new(401).with_body("Invalid token"));
}
After you run the signature validation or the parsing method, use the following methods exposed by the JWTClaims struct to access the JWT claims:
pub fn audience(&self) -> Option<Result<Vec<String>, JWTError>>
pub fn not_before(&self) -> Option<DateTime<Utc>>
pub fn expiration(&self) -> Option<DateTime<Utc>>
pub fn issued_at(&self) -> Option<DateTime<Utc>>
pub fn issuer(&self) -> Option<String>
pub fn jti(&self) -> Option<String>
pub fn nonce(&self) -> Option<String>
pub fn subject(&self) -> Option<String>
pub fn has_claim(&self, name: &str) -> bool
pub fn get_claim<T>(&self, name: &str) -> Option<T> where T: ValueRetrieval,
pub fn has_header(&self, name: &str) -> bool
pub fn get_header(&self, name: &str) -> Option<String>
pub fn get_claims(&self) -> pdk_script::Value
pub fn get_headers(&self) -> pdk_script::Value
The provided methods are designed to return each one of the standard JWT claims.
The get_claim method can return any standard or custom claim. Because get_claim supports different target variable types, the user must specify the output type. get_claim supports String, f64, Vec<String>, chrono::DateTime<chono::Utc>, and serde_json::Value output types. Because the claim might not exist in the token, you must wrap the type with an Option, for example:
let some_custom_claim: Option<String> = claims.get_claim("username");
The following example shows how to parse a JWT token, get a custom claim, and propagate it to the request headers from a wrapped function:
async fn filter(
state: RequestState,
) -> Flow<()> {
let headers_state = state.into_headers_state().await;
// Extract token
let token = TokenProvider::bearer(headers_state.handler())?;
if token.is_err() {
return Flow::Break(Response::new(401).with_body("Bearer not found"));
}
// Being "token" a String that contains a JWT token
let parsed_claims = JWTClaimsParser::parse(token.unwrap());
if claims.is_err() {
return Flow::Break(Response::new(401).with_body("Invalid token"));
}
let claims = claims.unwrap();
let username: Option<String> = claims.get_claim("username");
if let Some(custom_claim) = some_custom_claim {
headers_state
.handler()
.set_header("username", custom_claim.as_str());
}
Flow::Continue(())
}