Alexa Rust Webservice Verifier
Verify that incoming requests are from Alexa for custom, webservice skills.
Features
Both sync and async clients are provided by default. These are behind feature
flags sync
or async
, respectively.
sync
provides RequestVerifier
client
async
provides RequestVerifierAsync
client
Using
Example using Rouille server
and alexa_sdk for request deserialization
use crate::skill::process_request; use alexa_verifier::RequestVerifier; use log::{debug, error, info};
use rouille::{router, Request, Response};
use std::io::Read;
fn note_routes(request: &Request, verifier: &RequestVerifier) -> Response {
router!(request,
(POST) (/) => {
info!("Request received...");
let mut body = request.data().unwrap();
let mut body_bytes: Vec<u8> = vec![];
body.read_to_end(&mut body_bytes).unwrap();
let signature_cert_chain_url = request.header("SignatureCertChainUrl").unwrap_or("");
let signature = request.header("Signature").unwrap_or("");
let _request = serde_json::from_slice::<alexa_sdk::Request>(&body_bytes);
if let Err(e) = _request {
error!("Could not deserialize request");
error!("{:?}", e);
let response = Response::empty_400();
info!("Sending back response...");
debug!("{:?}", response);
return response;
}
let request = _request.unwrap();
debug!("{:?}", request);
if verifier
.verify(
signature_cert_chain_url,
signature,
&body_bytes,
request.body.timestamp.as_str(),
None
).is_err() {
error!("Could not validate request came from Alexa");
let response = Response::empty_400();
info!("Sending back response...");
debug!("{:?}", response);
return response;
};
debug!("Request is validated...");
let response = Response::json(&process_request(request));
info!("Sending back response...");
debug!("{:?}", response);
response
},
_ => Response::empty_404()
)
}
pub fn run() -> std::io::Result<()> {
info!("Starting server on 0.0.0.0:8086");
let verifier = RequestVerifier::new();
rouille::start_server("0.0.0.0:8086", move |request| {
note_routes(&request, &verifier)
});
}
License: MIT