Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use std::future::{ready, Ready};
- const IGNORE_ROUTES: [&str; 1] = ["/api/user/signin"];
- use actix_web::dev::{forward_ready, Service, ServiceRequest, ServiceResponse, Transform};
- use actix_web::http::{header::HeaderName, header::HeaderValue, Method};
- use actix_web::middleware::{ErrorHandlerResponse, ErrorHandlers};
- use actix_web::{Error, HttpResponse};
- use futures::future::LocalBoxFuture;
- use serde::{Deserialize, Serialize};
- #[derive(Debug, Serialize, Deserialize)]
- pub struct ResponseBody<T> {
- pub message: String,
- pub data: T,
- }
- impl<T> ResponseBody<T> {
- pub fn new(message: &str, data: T) -> ResponseBody<T> {
- ResponseBody {
- message: message.to_string(),
- data,
- }
- }
- }
- // There are two steps in middleware processing.
- // 1. Middleware initialization, middleware factory gets called with
- // next service in chain as parameter.
- // 2. Middleware's call method gets called with normal request.
- pub struct Authentication;
- // Middleware factory is `Transform` trait
- // `S` - type of the next service
- // `B` - type of response's body
- impl<S, B> Transform<S, ServiceRequest> for Authentication
- where
- S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
- S::Future: 'static,
- B: 'static,
- {
- type Response = ServiceResponse<B>;
- type Error = Error;
- type InitError = ();
- type Transform = AuthenticationMiddleware<S>;
- type Future = Ready<Result<Self::Transform, Self::InitError>>;
- fn new_transform(&self, service: S) -> Self::Future {
- ready(Ok(AuthenticationMiddleware { service }))
- }
- }
- pub struct AuthenticationMiddleware<S> {
- service: S,
- }
- impl<S, B> Service<ServiceRequest> for AuthenticationMiddleware<S>
- where
- S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
- S::Future: 'static,
- B: 'static,
- {
- type Response = ServiceResponse<B>;
- type Error = Error;
- type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;
- forward_ready!(service);
- fn call(&self, mut req: ServiceRequest) -> Self::Future {
- let mut authenticate_pass: bool = false;
- // get headers
- let headers = req.headers_mut();
- // append header
- headers.append(
- HeaderName::from_static("content-length"),
- HeaderValue::from_static("true"),
- );
- // if method was OPTIONS then automatically passes
- if Method::OPTIONS == *req.method() {
- authenticate_pass = true;
- }
- // if the path is in IGNORE_ROUTES then automatically passes
- for ignore_route in IGNORE_ROUTES.iter() {
- if req.path().starts_with(ignore_route) {
- authenticate_pass = true;
- }
- }
- println!("authenticate_pass {}", authenticate_pass);
- if authenticate_pass {
- let fut = self.service.call(req);
- Box::pin(async move {
- let res = fut.await?;
- Ok(res)
- })
- } else {
- Box::pin(async move {
- Ok(req.into_response(
- HttpResponse::Unauthorized()
- .json(ResponseBody::new("INVALID TOKEN", ""))
- .into_body(),
- ))
- })
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement