Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

jlwalker's avatar

Passport with cookies and CSRF protection.

I've been searching for days and can't find any information on how to properly use Passport with cookies. Every tutorial stores the access tokens in local storage despite countless articles stating this to be a security issue (XSS).

So after a user logs in, instead of sending the access token back with the response, I set it as a http only cookie. For incoming requests, I wrote custom middleware to check for the cookie and if present, I set the Authorization: Bearer header before the request is handled by the authentication middleware and the rest of the app.

This works perfectly, except that it seems to leave me vulnerable to CSRF attacks (right?). So I added the VerifyCsrfToken middleware to the api group, along with EncryptCookies and StartSession middleware. I defined the cookie session driver in my config. I am now getting a CSRF token mismatch error.

Does anyone know how to do this properly? As I said, I've been reading articles and playing around with different setups for days and can't find any detailed info on how to get it right. Hoping someone can help me out as I'm beginning to feel pretty confused with it all.

Thanks in advance.

0 likes
13 replies
jlwalker's avatar

@TOKOIWESLEY - Thanks @tokoiwesley.

As far as I understand it, that requires use of the web middleware group, and also requires a refresh before/after login. However, I'm doing everything in React so am not using the web middleware (other than initial page load).

1 like
jlwalker's avatar

@EJDELMONICO - I'm not sure how that would help -- the cookie would be available to javascript and so the token could be stolen through xss.

ejdelmonico's avatar

It's encrypted so it doesn't matter if someone steals it. They won't go through all that trouble to try and decrypt by guessing the key. For XSS to work, they would have to decrypt the cookie first. That is the whole point of using an encrypted cookie instead of the standard non-encrypted.

Cookies.set('name', 'value', { expires: 365, secure: true })

https://github.com/js-cookie/js-cookie/tree/latest#secure

jlwalker's avatar

@EJDELMONICO - Encryption requires a secret key. You can’t keep a secret key secret with client side code.

I had a skim through the docs, it doesn’t mention encryption. The secure option relates to whether or not the cookie should only be sent over https connections, not whether or not the cookie is encrypted.

1 like
ejdelmonico's avatar

The cookie will not be visible on a nonencrypted connection. HTTPS provides encryption. Demonstrate it yourself. Try accessing the cookie on an HTTP connection...it will not be accessible.

YeZawHein's avatar

Cookies vs local storage

Both of the mechanisms have their own pros and cons.It doesn't matter what you use.You should concentrate on XSS protection, that’s perfect of the protection. Everything is safe against a remote attacker as long as you use HTTPS and there is no XSS on your page. Your main concern should be avoiding XSS. If you have XSS on your page then basically everything is lost, the attacker will be able to attack the user’s session one way or other, it does not matter if you use cookies, local / session storage or IndexedDB, etc.

jlwalker's avatar

@YEZAWHEIN - Yes I think you’re right. I had the impression that with cookies you could make tokens invulnerable to xss but I realise now that you really can’t. Thanks

YeZawHein's avatar

@jlwalker

I realise now that you really can’t.

What that means?I give you just an advice.

localStorage uses essentially the same security policy as cookies; one of its core principles is that a domain cannot access localStorage data that was created under a different domain so there is no chance that a website could steal data from a different website. I don't want to dispute with you.If you want cookies prevent from csrf, use SameSite=strict cookie.

jlwalker's avatar

@YEZAWHEIN - I’m not disputing, I’m agreeing with you. Maybe I worded it wrong. I’m saying that if you have xss vulnerability, then whether you used cookies or local storage, attacker can send requests on behalf of someone else.

Also I’m talking about xss within my own site. That would be the same origin as the cookie / local storage data, so same-origin policy doesn’t apply. Therefore you should concentrate primarily on xss, like you said.

rn-code's avatar

@jlwalker I have the same setup as you do. I'm running Passport and setting the Authorization header manually. Did you find a solution for this CSRF token mismatch error?

Please or to participate in this conversation.