ys memos

Blog

Rustで簡単なJWTライブラリを実装してみた ~5. ヘッダー~


rust

2024/08/31


  1. 概要と使用例
  2. プロジェクト設定
  3. base64関連
  4. 署名アルゴリズム関連
  5. ヘッダ定義
  6. JWT本体の実装
  7. JWT本体のTest

本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 }
    }
}


mod algorithm;

use algorithm::Algorithm;

use serde::{Deserialize, Serialize};

use crate::error::Result;

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),
        })
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "UPPERCASE")]
pub enum Typ {
    Jwt,
}

AlgTypを持つ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 }
    }
}


関連タグを探す