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

Yesod Session Question (Sorry if wrong place) #1443

Open
sbditto85 opened this issue Sep 5, 2017 · 8 comments
Open

Yesod Session Question (Sorry if wrong place) #1443

sbditto85 opened this issue Sep 5, 2017 · 8 comments

Comments

@sbditto85
Copy link
Contributor

sbditto85 commented Sep 5, 2017

Anyone know if there is a way to have a session backend, but just “turn it off” for a request … meaning it doesn’t persist anywhere and basically just becomes a Map you can use during the request?

To motivate why i'm asking, I have an app that will be serving a website as well as have an API for other servers to interact with. When the servers are interacting with the app they don't need a session, its more of a save and forget, but the users will.

EDIT: It would seem that due to this line

let mkYesodReq = parseWaiRequest req session (isJust yreSessionBackend) mmaxLen
it is not possible correct?

If this is the wrong place to ask where is a better? I've tried the IRC channel on freenode and no luck.

@psibi
Copy link
Member

psibi commented Sep 5, 2017

You can probably check for the current route in the makeSessionBackend and disable or enable the session based on your route.

@sbditto85
Copy link
Contributor Author

makeSessionBackend doesn't have access to the request and is initialized in the beginning.

@paul-rouse
Copy link
Contributor

I am not really sure what you mean by "turn it off". Do you actually need to prevent the yesod app sending a session cookie in these cases? If not, there is nothing wrong with the client omitting the _SESSION cookie when making a request, providing you don't need authentication for the specific route, so your "other servers" could just ignore the session and not send a cookie. Your handler will still be able to do getSession, setSession etc, but of course they will start from a newly initialised SessionMap in this case. (All of this is assuming the default session backend, of course.)

@sbditto85
Copy link
Contributor Author

I apologize, Im using persistent sessions (https://github.com/yesodweb/serversession/tree/master/serversession-backend-persistent) instead of the regular frontend sessions. Since a token always get added to the session, every API request results in a new session being created in the database, which as you can imagine having thousands of empty sessions in the database is not really desirable.

During the request I don't mind having the map populated using the session functions, I would just like it to not persist if it is an API request as opposed to a client request.

Does that make sense?

Line where token is always added:

(\n -> Map.insert tokenKey (encodeUtf8 n) newSess)

This happens because reqToken is always a Just if you have useToken set to true in this function:

which is set to true by the previously mentioned line

let mkYesodReq = parseWaiRequest req session (isJust yreSessionBackend) mmaxLen
by isJust yreSessionBackend which comes from the makeSessionBackend in one of the "toWaiApp" function i.e.
, yreSessionBackend = sb

Have I misunderstood anything?

@paul-rouse
Copy link
Contributor

Ah! Yes, I completely see the problem now. Your analysis looks absolutely fine, too, so I am out of ideas at the moment. I'll come back if I think of anything more, or perhaps someone else will have an idea.

@sbditto85
Copy link
Contributor Author

Any ideas why a token is always added when there is a session backend? Is the token used for something other the CSRF, if not why isn't it only added by the CSRF middleware?

@sbditto85
Copy link
Contributor Author

So i found a work around which @psibi was actually pretty close to. In the SessionBackend type is a newtype for a function that takes a Wai Request and then returns an IO with a tuple of session data and a save function. I wrapped the that save function so that if the Wai Request has a specific header then it returns a function that does nothing, otherwise it returns the original save function.

Still would like to know if there is a better solution and why a token is assigned the session on every request if there is a session backend.

@MaxGabriel
Copy link
Member

@sbditto85 The CSRF middleware was added to support checking the CSRF token in the headers of the request (previously only checking for a hidden field in a <form> was supported), and it was added years after the session middleware. I haven't investigated if there are uses other than that.

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

No branches or pull requests

4 participants