/
germanubis
/
jsonwebtoken
Обзор
Документация
Войти
/
germanubis
/
jsonwebtoken
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/jws.rs
84 строки
3 KB
Vincent Prouillet
cargo fmt post edition bump
29 сен 2025, 22:37
29 сен 2025, 22:37
e72a3d4
Код
Авторство
О чём код?
//! JSON Web Signatures data type. use std::marker::PhantomData; use crate::crypto::sign; use crate::errors::{ErrorKind, Result, new_error}; use crate::serialization::{DecodedJwtPartClaims, b64_encode_part}; use crate::validation::validate; use crate::{DecodingKey, EncodingKey, Header, TokenData, Validation}; use crate::decoding::{jwt_verifier_factory, verify_signature_body}; use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; /// This is a serde-compatible JSON Web Signature structure. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Jws<C> { /// The base64 encoded header data. /// /// Defined in [RFC7515#3.2](https://tools.ietf.org/html/rfc7515#section-3.2). pub protected: String, /// The base64 encoded claims data. /// /// Defined in [RFC7515#3.2](https://tools.ietf.org/html/rfc7515#section-3.2). pub payload: String, /// The signature on the other fields. /// /// Defined in [RFC7515#3.2](https://tools.ietf.org/html/rfc7515#section-3.2). pub signature: String, /// Unused, for associating type metadata. #[serde(skip)] pub _pd: PhantomData<C>, } /// Encode the header and claims given and sign the payload using the algorithm from the header and the key. /// If the algorithm given is RSA or EC, the key needs to be in the PEM format. This produces a JWS instead of /// a JWT -- usage is similar to `encode`, see that for more details. pub fn encode<T: Serialize>( header: &Header, claims: Option<&T>, key: &EncodingKey, ) -> Result<Jws<T>> { if key.family != header.alg.family() { return Err(new_error(ErrorKind::InvalidAlgorithm)); } let encoded_header = b64_encode_part(header)?; let encoded_claims = match claims { Some(claims) => b64_encode_part(claims)?, None => "".to_string(), }; let message = [encoded_header.as_str(), encoded_claims.as_str()].join("."); let signature = sign(message.as_bytes(), key, header.alg)?; Ok(Jws { protected: encoded_header, payload: encoded_claims, signature, _pd: Default::default(), }) } /// Validate a received JWS and decode into the header and claims. pub fn decode<T: DeserializeOwned>( jws: &Jws<T>, key: &DecodingKey, validation: &Validation, ) -> Result<TokenData<T>> { let header = Header::from_encoded(&jws.protected)?; let message = [jws.protected.as_str(), jws.payload.as_str()].join("."); let verifying_provider = jwt_verifier_factory(&header.alg, key)?; verify_signature_body( message.as_bytes(), jws.signature.as_bytes(), &header, validation, verifying_provider, )?; let decoded_claims = DecodedJwtPartClaims::from_jwt_part_claims(&jws.payload)?; let claims = decoded_claims.deserialize()?; validate(decoded_claims.deserialize()?, validation)?; Ok(TokenData { header, claims }) }