未经验证阅读声明。 , 了解结果 return

Read claims without verification. , Understanding the Result return

我在 Rust 中使用 JWT,遇到过导航时遇到一些问题的情况。我对 Rust 和 JWT 都是新手,所以请多多关照。

我正在使用找到的 jwt 板条箱 here

我想要做的是创建一个包含 header 和声明的签名 JWT。声明只有一个字段,issuer。我可以毫无问题地发行新令牌。

fn issue_token(user_id: &str) -> Result<String, &'static str> {
    let header: Header = Default::default();
   
    let claims = RegisteredClaims {
        issuer: Some("user who issued token".into()),
        subject: Some(user_id.into()),
        ..Default::default()
    };

    let unsigned_token = Token::new(header, claims);

    let key: Hmac<Sha256> =
        Hmac::new_from_slice("secret_key".as_bytes()).map_err(|_e| "Invalid key")?;

    let signed_token = unsigned_token
        .sign_with_key(&key)
        .map_err(|_e| "Sign error")?;

    Ok(signed_token.into())
}

issuer 声明很重要。因为有不同的进程有自己的令牌。所有 issuers 都已经在主服务器上注册了他们的 secret。现在,其他用户将连接到特定的 issuer,验证用户身份,并发布已签名的 JWT。用户不知道 secret 是什么,只有 issuer 和服务器之间才知道。

我在 server-side 上尝试做的是读取 claims 以确定 issuer 是谁。一旦我知道 issuer 是谁,我就知道使用什么秘密来验证签名。

我在验证令牌时没有遇到任何问题,一旦我验证了令牌,我就可以阅读声明。但我需要先阅读声明,然后再验证令牌。

除了签名和验证的基本示例之外,文档对我来说很清楚。

查看 crate 的文档,here,我无法弄清楚如何实现我正在尝试做的事情。

我找到了我认为是我正在寻找的东西,hereparse_unverifiedUnverified,但我正在努力弄清楚如何使用要么。

parse_unverified 看起来是两者中更有前途的一个,正如文档所述 Not recommended. Parse the header and claims without checking the validity of the signature

有人对 Rust 和 jwt crate 有任何经验吗?

我相信我已经部分弄明白了。

首先导入正确的 crate 选项

use jwt::{Claims, Error, Header, RegisteredClaims, Token, Unverified, VerifyWithKey};

然后我可以创建一个新变量,比如

let unverified: Result<Token<Header, Claims, Unverified<'_>>, Error> =
            Token::parse_unverified(token);

现在可以正常运行了,构建和运行都很好。我现在遇到的问题实际上是现在正在解析 unverified

我看得越多,我认为这可能与 JWT 关系不大,而与标准 Rust 操作关系更大。作为返回 Result.

有什么见解吗?

这是一个标准的 Result,所以您必须像往常一样用 ? 打开它才能找到里面的 Token。即使这不验证签名,它仍然可能由于无效的 base64/JSON 编码或 JWT 框架而失败。 (如果这里有错误,令牌甚至在结构上都不有效,所以没有进一步的意义。)

let unverified: Token<Header, Claims, _> = Token::parse_unverified(token)?;

现在您可以在 unverified 上使用 Token 提供的任何工具,例如unverified.claims().

您可能希望使用 RegisteredClaims 进行解析,这样您可以更轻松地访问发行人字段:

let unverified: Token<Header, RegisteredClaims, _> =
    Token::parse_unverified(token)?;

let issuer = unverified.claims().issuer.as_ref()
    .ok_or(MissingIssuerError)?;

issuer 将是 &String。 (MissingIssuerError 是错误的占位符,如果发行者字段不存在,您可以提出错误。)