use actix_service::{Service, Transform}; use actix_web::dev::{ServiceRequest, ServiceResponse}; use actix_web::{http, Error, HttpResponse}; use futures::future::{ok, Either, FutureResult}; use futures::Poll; pub struct CheckLogin; impl Transform for CheckLogin where S: Service, Error = Error>, S::Future: 'static, { type Request = ServiceRequest; type Response = ServiceResponse; type Error = Error; type InitError = (); type Transform = CheckLoginMiddleware; type Future = FutureResult; fn new_transform(&self, service: S) -> Self::Future { ok(CheckLoginMiddleware { service }) } } pub struct CheckLoginMiddleware { service: S, } impl Service for CheckLoginMiddleware where S: Service, Error = Error>, S::Future: 'static, { type Request = ServiceRequest; type Response = ServiceResponse; type Error = Error; type Future = Either>; fn poll_ready(&mut self) -> Poll<(), Self::Error> { self.service.poll_ready() } fn call(&mut self, req: ServiceRequest) -> Self::Future { // We only need to hook into the `start` for this middleware. let is_logged_in = false; // Change this to see the change in outcome in the browser if is_logged_in { Either::A(self.service.call(req)) } else { // Don't forward to /login if we are already on /login if req.path() == "/login" { Either::A(self.service.call(req)) } else { Either::B(ok(req.into_response( HttpResponse::Found() .header(http::header::LOCATION, "/login") .finish() .into_body(), ))) } } } }