Initial
This commit is contained in:
commit
a8b62a4e89
6 changed files with 1651 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/target
|
1512
Cargo.lock
generated
Normal file
1512
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
12
Cargo.toml
Normal file
12
Cargo.toml
Normal file
|
@ -0,0 +1,12 @@
|
|||
[package]
|
||||
name = "actix-middleware-demo"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
actix-web = { version = "4.4.0", features = ["rustls"] }
|
||||
futures-util = "0.3.29"
|
||||
serde = { version = "1.0.190", features = ["derive"] }
|
||||
serde_json = "1.0.107"
|
1
postdata.nu
Normal file
1
postdata.nu
Normal file
|
@ -0,0 +1 @@
|
|||
http post -t application/json http://localhost:8080 { demo: "Whatever 123" }
|
89
src/auth_middleware.rs
Normal file
89
src/auth_middleware.rs
Normal file
|
@ -0,0 +1,89 @@
|
|||
use std::future::{ready, Ready};
|
||||
|
||||
use actix_web::{
|
||||
dev::{forward_ready, Service, ServiceRequest, ServiceResponse, Transform},
|
||||
Error, HttpMessage,
|
||||
};
|
||||
use futures_util::{future::LocalBoxFuture, FutureExt};
|
||||
use std::rc::Rc;
|
||||
|
||||
// This is where you would store your authentication data
|
||||
pub struct AuthData;
|
||||
pub struct AuthenticationResult;
|
||||
|
||||
impl AuthData {
|
||||
pub async fn authenticate(
|
||||
&self,
|
||||
_id: Option<String>,
|
||||
) -> Result<Option<AuthenticationResult>, Error> {
|
||||
Ok(Some(AuthenticationResult))
|
||||
}
|
||||
}
|
||||
|
||||
pub type AuthenticationInfo = Rc<AuthenticationResult>;
|
||||
pub struct AuthenticationMiddleware<S> {
|
||||
auth_data: Rc<AuthData>,
|
||||
service: Rc<S>,
|
||||
}
|
||||
|
||||
impl<S, B> Service<ServiceRequest> for AuthenticationMiddleware<S>
|
||||
where
|
||||
S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error> + 'static,
|
||||
{
|
||||
type Response = ServiceResponse<B>;
|
||||
type Error = Error;
|
||||
type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;
|
||||
|
||||
forward_ready!(service);
|
||||
|
||||
fn call(&self, req: ServiceRequest) -> Self::Future {
|
||||
let srv = self.service.clone();
|
||||
let auth_data = self.auth_data.clone();
|
||||
|
||||
async move {
|
||||
let id = req
|
||||
.headers()
|
||||
.get("X-Auth-Id")
|
||||
.map(|id| id.to_str().unwrap().to_owned());
|
||||
let auth = auth_data.authenticate(id).await?;
|
||||
if let Some(auth) = auth {
|
||||
req.extensions_mut()
|
||||
.insert::<AuthenticationInfo>(Rc::new(auth));
|
||||
}
|
||||
|
||||
let res = srv.call(req).await?;
|
||||
Ok(res)
|
||||
}
|
||||
.boxed_local()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AuthenticateMiddlewareFactory {
|
||||
auth_data: Rc<AuthData>,
|
||||
}
|
||||
|
||||
impl AuthenticateMiddlewareFactory {
|
||||
pub fn new(auth_data: AuthData) -> Self {
|
||||
AuthenticateMiddlewareFactory {
|
||||
auth_data: Rc::new(auth_data),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<S, B> Transform<S, ServiceRequest> for AuthenticateMiddlewareFactory
|
||||
where
|
||||
S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error> + 'static,
|
||||
{
|
||||
type Response = ServiceResponse<B>;
|
||||
type Error = Error;
|
||||
type Transform = AuthenticationMiddleware<S>;
|
||||
type InitError = ();
|
||||
type Future = Ready<Result<Self::Transform, Self::InitError>>;
|
||||
|
||||
fn new_transform(&self, service: S) -> Self::Future {
|
||||
ready(Ok(AuthenticationMiddleware {
|
||||
auth_data: self.auth_data.clone(),
|
||||
service: Rc::new(service),
|
||||
}))
|
||||
}
|
||||
}
|
36
src/main.rs
Normal file
36
src/main.rs
Normal file
|
@ -0,0 +1,36 @@
|
|||
use actix_web::{get, post, web::Json, App, HttpResponse, HttpServer, Responder};
|
||||
|
||||
use serde::Deserialize;
|
||||
mod auth_middleware;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct Data {
|
||||
demo: String,
|
||||
}
|
||||
|
||||
#[get("/")]
|
||||
async fn index() -> impl Responder {
|
||||
HttpResponse::Ok().body("Actix is alive!")
|
||||
}
|
||||
|
||||
#[post("/")]
|
||||
async fn postfunction(json: Json<Data>) -> impl Responder {
|
||||
HttpResponse::Ok().body(json.demo.clone())
|
||||
}
|
||||
|
||||
#[actix_web::main] // Same as #[tokio::main]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
println!("Serving at http://localhost:8080");
|
||||
HttpServer::new(|| {
|
||||
App::new()
|
||||
.wrap(auth_middleware::AuthenticateMiddlewareFactory::new(
|
||||
auth_middleware::AuthData,
|
||||
))
|
||||
.service(index)
|
||||
.service(postfunction)
|
||||
})
|
||||
.bind("0.0.0.0:8080")
|
||||
.unwrap()
|
||||
.run()
|
||||
.await
|
||||
}
|
Loading…
Reference in a new issue