Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Access session in BeforeMiddleware panics #6

Open
frjonsen opened this issue Mar 9, 2017 · 3 comments
Open

Access session in BeforeMiddleware panics #6

frjonsen opened this issue Mar 9, 2017 · 3 comments

Comments

@frjonsen
Copy link

frjonsen commented Mar 9, 2017

Hi. I'm trying to access the session in a BeforeMiddleware, in order to check if the request is authenticated. This is my middleware:

struct SessionMiddleware<C: Connection> {
    connection: Arc<C>
}

impl typemap::Key for User {
    type Value = User;
}

impl<C: Connection + 'static> BeforeMiddleware for SessionMiddleware<C> {

    fn before(&self, req: &mut Request) -> IronResult<()> {
        use ::entities::Session;
        use iron_sessionstorage::{SessionRequestExt,Value};
        if let Some(session) = try!(req.session().get::<Session>()) {
            let sess: String = session.into_raw();
            let connection = self.connection.clone();
            let valid_seconds = ::CONFIG.read().unwrap().get_int("sessions.duration");
            if let Ok(Some(user)) = connection.verify_session(&sess, valid_seconds) {
            req.extensions.insert::<User>(user);
            }
        }
        Ok(())
    }
}

This is causing a panic here: https://github.com/iron/iron-sessionstorage/blob/master/src/lib.rs#L131

Is there any way to do what I'm attempting to do, or will I have to move this to the Handlers? I'd rather not put it in the Handlers, since I want to do this for every request, which seems to be pretty much the entire point of BeforeMiddlewares. I suspect that the fact that sessionstorage is an AroundMiddleware makes it impossible to access Sessions in a BeforeMiddleware?

@untitaker
Copy link
Member

Since AroundMiddleware.around returns a handler, you can call my_sessionstorage.around(my_chain) and give the result to Iron.

@aetsoftware
Copy link

aetsoftware commented Nov 1, 2017

Maybe I'm not understanding what's going on, but I'm getting the same thing I believe. Could you clearify the answer above? Here's some of my implementation:

pub struct Authentication;

impl typemap::Key for Authentication { type Value = u64; }

impl BeforeMiddleware for Authentication {

	fn before(&self, req: &mut Request) -> IronResult<()> {
		let session = req.session();    //Panics here
		if let Some(session) = try!(session.get::<Login>()) {
			let sess: String = session.into_raw();
			//Continue
		}
		Ok(())
	}
}

//Usage in main:
let mut chain = Chain::new(router);

chain.link_around(SessionStorage::new(SignedCookieBackend::new(my_secret)));
chain.link_before(Authentication);

Iron::new(chain).http("localhost:3000").unwrap();

@untitaker
Copy link
Member

untitaker commented Nov 5, 2017 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants