2024/08/31
目次
はじめに
本Partでは、ヘッダーの定義を行う。
基本的には、サポートするアルゴリズムなどを列挙し、JWTをの変換に併せたserde
の設定を書く流れとなる。
コード全文
src/jwt/header/mod.rs
mod algorithm;
use algorithm::Algorithm;
use serde::{Deserialize, Serialize};
use crate::error::Result;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum Alg {
HS256,
}
impl Alg {
pub(super) fn sign<T: AsRef<[u8]>>(&self, secret: &[u8], data: T) -> Result<Vec<u8>> {
Ok(match self {
Self::HS256 => algorithm::HS256::init(secret, data)?.sign(),
})
}
pub(super) fn verify<T: AsRef<[u8]>>(
&self,
secret: &[u8],
data: T,
signature: &[u8],
) -> Result<bool> {
Ok(match self {
Self::HS256 => algorithm::HS256::init(secret, data)?.verify(signature),
})
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "UPPERCASE")]
pub enum Typ {
Jwt,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Header {
pub(super) alg: Alg,
typ: Typ,
}
impl Header {
pub fn new(alg: Alg) -> Self {
Self { alg, typ: Typ::Jwt }
}
}
解説
useなど
mod algorithm;
use algorithm::Algorithm;
use serde::{Deserialize, Serialize};
use crate::error::Result;
Alg
Alg
にはサポートするアルゴリズムを列挙する。
これをpub
にしているのは、ライブラリとして Alg
指定してJwt
を生成するためである。
また、メソッドを定義しているのは、Jwt
構造体から署名や検証を、アルゴリズムによる差分を意識せずに実行できるようにするためである。これらのメソッドは、視認性をAlg
よりも狭めている。
このメソッド群により、サポートする署名アルゴリズムの追加が容易になり、それによって上位の構造体への影響が少なくなる。
この箇所は、特段パフォーマンスを考慮しなかったが、sign()
, verify()
を連続して行うようなシチュエーションが考えられる場合は、Jwt
生成時にこれらのインスタンスをセットで生成し、.clone()
で使いまわすようにすると良いのかもしれない(どちらがよいのかはベンチマークをとり比較する)。
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum Alg {
HS256,
}
impl Alg {
pub(super) fn sign<T: AsRef<[u8]>>(&self, secret: &[u8], data: T) -> Result<Vec<u8>> {
Ok(match self {
Self::HS256 => algorithm::HS256::init(secret, data)?.sign(),
})
}
pub(super) fn verify<T: AsRef<[u8]>>(
&self,
secret: &[u8],
data: T,
signature: &[u8],
) -> Result<bool> {
Ok(match self {
Self::HS256 => algorithm::HS256::init(secret, data)?.verify(signature),
})
}
}
Typ
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "UPPERCASE")]
pub enum Typ {
Jwt,
}
Header
Alg
とTyp
を持つHeader
構造体を定義し、初期化用の関連関数を準備しておく。
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Header {
pub(super) alg: Alg,
typ: Typ,
}
impl Header {
pub fn new(alg: Alg) -> Self {
Self { alg, typ: Typ::Jwt }
}
}