2024/08/31
目次
はじめに
本Partでは、JWT本体のテストを行う。
Jwt
構造体はライブラリ本体であり、大きくなりがちだと考え、ファイル分割してtestを書いた。
コード全文
src/jwt/tests.rs
use serde::{Deserialize, Serialize};
use crate::error::Result;
use super::Jwt;
// Define for Testing
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TestPayload {
sub: String,
name: String,
iat: u64,
}
pub type TestJwt = Jwt<TestPayload>;
const VALID_TOKEN: &str = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.mpHl842O7xEZjgQ8CyX8xYLDoEORGVMnAxULkW-u8Ek";
const TAMPERED_TOKEN : &str = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkxIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.mpHl842O7xEZjgQ8CyX8xYLDoEORGVMnAxULkW-u8Ek";
const SECRET: &[u8; 11] = b"test-secret";
#[test]
fn decode_encode() -> Result<()> {
let jwt = TestJwt::decode(VALID_TOKEN)?;
let reencoded = jwt.encode()?;
assert_eq!(VALID_TOKEN, reencoded);
Ok(())
}
#[test]
fn verify() -> Result<()> {
let jwt = TestJwt::decode(VALID_TOKEN)?;
assert!(jwt.verify(SECRET)?);
assert!(!jwt.verify(b"dummy-secret")?);
Ok(())
}
#[test]
fn sign() -> Result<()> {
let mut jwt = TestJwt::decode(VALID_TOKEN)?;
assert!(jwt.verify(SECRET)?);
jwt.sign(b"")?;
assert!(!jwt.verify(SECRET)?);
jwt.sign(SECRET)?;
assert!(jwt.verify(SECRET)?);
Ok(())
}
#[test]
fn tampering() -> Result<()> {
let mut jwt = TestJwt::decode(TAMPERED_TOKEN)?;
assert!(!jwt.verify(SECRET)?);
jwt.sign(b"")?;
assert!(!jwt.verify(SECRET)?);
jwt.sign(SECRET)?;
assert!(jwt.verify(SECRET)?);
Ok(())
}
解説
use
use serde::{Deserialize, Serialize};
use crate::error::Result;
use super::Jwt;
Test用のPayloadや定数の準備
// Define for Testing
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TestPayload {
sub: String,
name: String,
iat: u64,
}
pub type TestJwt = Jwt<TestPayload>;
const VALID_TOKEN: &str = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.mpHl842O7xEZjgQ8CyX8xYLDoEORGVMnAxULkW-u8Ek";
const TAMPERED_TOKEN : &str = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkxIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.mpHl842O7xEZjgQ8CyX8xYLDoEORGVMnAxULkW-u8Ek";
const SECRET: &[u8; 11] = b"test-secret";
encode/decode
まずは基本的な用途、トークンをデコードして、そのままエンコードしたときに同じトークンになるかをtestする。
#[test]
fn decode_encode() -> Result<()> {
let jwt = TestJwt::decode(VALID_TOKEN)?;
let reencoded = jwt.encode()?;
assert_eq!(VALID_TOKEN, reencoded);
Ok(())
}
verify
トークンを検証が成功するか、失敗するかをtestする。
#[test]
fn verify() -> Result<()> {
let jwt = TestJwt::decode(VALID_TOKEN)?;
assert!(jwt.verify(SECRET)?);
assert!(!jwt.verify(b"dummy-secret")?);
Ok(())
}
sign
ここでは、正常なトークン・シークレットの組から、ニセのシークレットで署名を変更て失敗することのtest、および正常なシークレットで署名を変更して成功することのtestを行っている。
#[test]
fn sign() -> Result<()> {
let mut jwt = TestJwt::decode(VALID_TOKEN)?;
assert!(jwt.verify(SECRET)?);
jwt.sign(b"")?;
assert!(!jwt.verify(SECRET)?);
jwt.sign(SECRET)?;
assert!(jwt.verify(SECRET)?);
Ok(())
}
tampering
改竄耐性のtest。これは、改ざんされたトークンのverify
が失敗することのtestをし、その後に署名を変更して成功することのtestを行っている。
#[test]
fn tampering() -> Result<()> {
let mut jwt = TestJwt::decode(TAMPERED_TOKEN)?;
assert!(!jwt.verify(SECRET)?);
jwt.sign(b"")?;
assert!(!jwt.verify(SECRET)?);
jwt.sign(SECRET)?;
assert!(jwt.verify(SECRET)?);
Ok(())
}
おわりに
ここまで完了すると、1. 概要と使用例で記述したmain.rs
を cargo run
で動かせるようになります。