DEV Community

Discussion on: The Ultimate Guide to JWT client side auth (Stop using local storage!!!)

Collapse
 
cyberhck profile image
Nishchal Gautam

A few things, I don't agree with:

  • When you say refresh token is a JWT but can't access, are you storing that in db? What is the expiry time? Because it must be enough long lived, say you did 3 months, and you're relying on JWT properties (signing key) to validate refresh token, then when I get access to your refresh token, how will you log me out? Unless you keep a list of blocklist of refresh token, (then how would you block those token anyway? Because you don't know, as you didn't save them), this means once I get a refresh token, you are duped. I suggest falling back to opaque tokens which reside in db, and you can show all the sessions in user's security page and you can simply revoke those refresh token, which means no more new JWT at least. (and it's more cheap to keep a blocklist of JWT with lower expiry time if you need instant signout)

  • I'm not saying middleware does a 401 check, if you write your middleware correctly it shouldn't return 401 because of expired JWT, here's a kinda rough middleware for tinka:

export class RefreshTokenMiddleware implements IMiddleware<IFetchRequest, Promise<IFetchResponse<any>>> {
    public async process(options: IFetchRequest, next: (nextOptions: IFetchRequest) => Promise<IFetchResponse<any>>): Promise<IFetchResponse<any>> {
        if (this.hasJwtExpired(options)) {
             const jwt = await refreshJwt(...)
             // save this jwt so we can use later
             options.headers["authorization"] = jwt;
        }
        return await next(options);
    }
    private hasJwtExpired(options: IFetchRequest): boolean {
        // if jwt doesn't even exist, I guess you can think of it like a guest mode, and you should just return false,
        // compare the expiry timestamp with current timestamp and return true or false,
    }
}
Enter fullscreen mode Exit fullscreen mode

This way just before you make an API call, it ensures there's a valid JWT on request. (There's nothing wrong with having setTimeout but think about opening a tab in new browser, how many JWT do you want to actually store in db, a lot of people use multiple tabs and that'll invoke refresh token in each tab if we do setTimeout, but with this since it's done just before making a request, opening a new tab is okay.

"You just need to configure them." I don't think you understand what we meant. A lot of people are now blocking 3rd party cookies, I block 3rd party myself, which means, no matter what you do on your end, since I'm blocking 3rd party cookies, it simply won't work.

No, I mean I was agreeing with keeping tokens in cookie, but JWT must be accessible on client side, because if not, then how can I add authorization header for my API calls? If you want to say "don't use authorization header, just let API read those cookies", then I'm gonna stop even trying :)

Thread Thread
 
cyberhck profile image
Nishchal Gautam

also this:

Google will join Safari and Firefox in blocking third-party cookies in its Chrome web browser. However, unlike those browsers (which have already started blocking them by default),

Thread Thread
 
daniguardiola profile image
Dani Guardiola_

This post is misinformed. The only thing that had to change about the situation is to stop being vulnerable to XSS. As long as there's a token, it can be stolen, no matter how many steps it takes from having the token to using it to access the account. Making those tokens short-lived is a good practice but doesn't change the facts.

I'm with you brother.