#Session, Mobile App & Web app

33 messages · Page 1 of 1 (latest)

half pawn
#

Hey, I wanna use Nest it to build an API which will be used by an Expo app & a NextJS SPA. I've read a lot of documentation about how to deal with sessions, but im still not sure how to do it.
I wanted the API to send back a httpOnly Cookie (with either JWT or session ID) when the user logs in but the mobile app would not be able to store it as its httpOnly (or am I wrong ?)

What would be some ways to deal with this problem ?
Thanks !

sinful sequoia
#

Either you can have 2 different authorization schemes for web and mobile app, or don't use cookies at all and send the token in the Authorization header. In the react, there should be adapters for local storage both for web and for native

half pawn
#

Do you mean that I should pass the token in response and then store it the way I want in web & native app
My plan was to store it in cookie / native securestore and send it back in Authorization header, yea.
But I was not sure if it was a good practice for the api to send the tokens in json instead of a secured cookie
If I go with Jwts, im reading everywhere that I should keep the access token in memory, do they mean like a variable or react Context in the case of a NextJS app ?

And if I wanted to have 2 differents authorization schemes for web & mobile, would that just be two endpoints that I call on my clients like api/auth/web & api/auth/mobile ?

Thanks for your help, its really hard to figure out how to handle auth & session properly

sinful sequoia
#

Yes, it's pretty standard for login apis to send the token in a json reponse (look up how the OAuth flow works). If you used a httponly cokie, you couldn't read it on the client

#

Yes, you'd have 2 different login endpoints. But all your other endpoints would have to support both auth schemes.

#

If you go with OAuth, you'll generate a pair of a refresh token and access token. The refresh token (which you store on the client and on the back end for lookup) is used to retrieve a new access token which is short lived and is used to access your API. This one is not stored persistently anywhere.

half pawn
#

Thanks for your answer !
once again I've spent the day reading docs about all this, but I think im figuring something out, tell me what you think:

Client logs in
The API sends an accessToken and a refreshToken to the client
The API stores the user ID, refreshToken, and token expiration date in the database
The client stores both tokens in localStorage or an httpOnly cookie on the web, and SecureStore on mobile.
On each request, the client sends both the accessToken and the refreshToken to the API
The API takes care of all verifications, and if the accessToken is expired, the API generates a new pair of tokens, update the database and then proceeds with the initial request

I thought about just sending the accessToken and calling a /refresh endpoint when its expired using a middleware in Next, but im not sure I can reproduce it in the Expo App

Any suggestions? Thanks !

sinful sequoia
cinder sigil
#

On each request, the client sends both the accessToken and the refreshToken to the API
To clarify this, the client should only send the access token and as long as it is valid, you give access (thus the name). As papooch noted, if the access token isn't valid, in most cases because it is expired, your client should send a request to the refresh access point with the refresh token (thus the name). If the refresh token is valid, the client will get a new refresh and access token and the process starts from the beginning. If the refresh token is invalid, the user is considered logged out.

Also, access tokens can be saved in memory on the client. Refresh tokens should be saved in an http-only cookie.

half pawn
#

Thanks for your help, I will try the latest solution on Expo then, it seemed better to me too.
But I wonder, if I store the refreshToken in a cookie, it will be sent on every request anyway, no ? isnt it a problem ?
Would I really need to store the refreshToken on client if I store it on database ?
And by saving the access token in memory, you mean in a variable right ? Im not sure how to handle this client-side, I need to check

cinder sigil
#

@half pawn

if I store the refreshToken in a cookie, it will be sent on every request anyway, no ? isnt it a problem ?
Not if you put in a path on the cookie for your refresh endpoint.

Would I really need to store the refreshToken on client if I store it on database ?
Yes, because how would you know which client is refreshing? The client uses the refresh token as "access" to get new tokens. The refresh token is basically like a key to enter the token warehouse. 🙂

And by saving the access token in memory, you mean in a variable right ? Im not sure how to handle this client-side, I need to check

In memory via variable and in local storage, because you'd want the token to work in other windows and tabs of the browser.

half pawn
#

Oooh, I can make it so the cookie will only be sent on a certain path, great, I have spent days reading about jwt and session handling and its the first time I've heard about this, that will help me a lot, thanks

I'll try to figure out how to handle the middleware in Expo and i'll be good, thanks for your help !

sinful sequoia
#

I can make it so the cookie will only be sent on a certain path

I totally didn't know this too 🤯 How does that work? I thought cookies are only bound to a domain.

left egret
#

Path + Domain. You can set the Path= attribute of a cookie. / means all routes for the domain, and I believe from there it works based on substring matching subdirectory matching. Here's the MDN docs

cinder sigil
#

Wow. I knew something papooch didn't? I'll have to mark that in my calendar. 😄

half pawn
#

Hello again !
Would it be correct to do something like this in my jwt strategy on each request to handle both my web & mobile requests in the same strategy?
if (req.headers.cookie['access_token']) {
token = req.cookies['access_token'];
} else {
token = req.headers['authorization'];
}

cinder sigil
#

@half pawn - I've never worked with a mobile app. Can't a mobile app send headers?

half pawn
#

Yes thats what im planning to do, but with my web app sending the access token in a cookie

#

or u meant my mobile app sending it as a cookie too ?

cinder sigil
#

Ah, the other way around. Why can't your web app send an authorization header?

half pawn
#

I can, but I thought that if I store the tokens in cookies, it would perhaps be better to send them as cookies

cinder sigil
#

Not necessary for the access token, if it is short lived (only minutes TTL).

half pawn
#

Yea it will be short lived
I thought it would maybe not be optimal to store it in a cookie, and then to retrieve it before every request to send it as an Authorization Header, idk

cinder sigil
#

Well, your login response could just send it as part of the body. Also your refresh response.

#

No cookie needed.

half pawn
#

Yes thats the plan too, but Im still figuring out how to store the tokens in my web app to keep them between pages and sending the access token on every request

cinder sigil
#

Local Storage.

half pawn
#

isnt a bit unsafe and vulnerable to xss ?

#

Also in my web app, the middleware has no access to the client localStorage, making it a bit harder to handle than cookies

cinder sigil
#

Local storage is global via the web storage api, isn't it? And, hopefully you are sanitizing your user input to avoid XSS. In other words, if you've allowed XSS attackers to get scripts into your client app, you have other serious security issues.

half pawn
#

NextJS middleware has no access to client-side things like localStorage. I thought about having a "home made" fetch handling the token logic instead of the middleware, that I would use in every request but im not sure either if its a good practice

cinder sigil
#

Yeah, good luck with all that.

#

I've not worked with NextJS so can't help.