JWT認証
authed🔗
authed
キーワードと@claim
引数を記述するとJWT認証を利用するコードを生成できるようになります。
type Token {
token: string
}
type Claim {
iss: string
sub: string
iat: int
exp: int
}
interface API {
function register(user_name: string) -> Token
authed function get_user_name(@claim: Claim) -> string
}
生成されるコード🔗
JWT認証を利用する場合はJwtValidator
が作成され、JWTのトークンの検証用実装を強制されます。
pub trait JwtValidator {
fn validate<T: serde::de::DeserializeOwned>(token: &str) -> Result<T, ()>;
}
生成後に実装をすることでJWTを利用できます。
(Rustの実装にはjsonwebtoken
とasync-trait
とtokio(features = ["full"])
クレートが必要です)
use api::{
serve,
types::{Claim, JwtValidator, API, Token},
};
use async_trait::async_trait;
use jsonwebtoken::{DecodingKey, EncodingKey, Header, Validation};
struct Server {}
#[async_trait]
impl API for Server {
async fn register(&self, user_name: String) -> String {
let token = jsonwebtoken::encode(
&Header::default(),
&Claim {
iss: "localhost".to_string(),
iat: 0,
sub: user_name,
exp: i64::MAX,
},
&EncodingKey::from_secret(SECRET.as_bytes()),
)
.unwrap();
Token { token }
}
async fn get_user_name(&self, claim: Claim) -> String {
println!("Login : {}", &claim.sub);
claim.sub
}
}
static SECRET: &'static str = "RUST IS GOOD!";
impl JwtValidator for Server {
fn validate<T: serde::de::DeserializeOwned>(token: &str) -> Result<T, ()> {
let claim = jsonwebtoken::decode(
token,
&DecodingKey::from_secret(SECRET.as_bytes()),
&Validation::default(),
)
.map_err(|_| ())?
.claims;
Ok(claim)
}
}
#[tokio::main]
async fn main() {
let server = Server {};
serve(server, "localhost:3000").await.unwrap();
}
また、クライアント側のメソッドの第一引数にはトークンが要求されるようになります。
class API {
public async get_user_name(__token: string): Promise<string> {
}
}
async function main() {
const api = new API("http://localhost:3000");
const token = await api.register("typescript user!");
const name = await api.get_user_name(token.token);
}