0

In my VueJS 3 SPA I have some routes that are protected. For example "/user". I use a JWT that I get from a backend. I store the JWT in a cookie. I have some functions and attributes that I have stored in a reactive access.js (simple storage).

// access.js
export const access = reactive({
    isAuth: false,

    setAuth(a) {
        this.isAuth = a;
    },
    
    setToken(token) {
        this.setAuth(true);
        comhelper.setToken(token, settings); // set cookie with token
    },

    async getToken() {
        return await comhelper.getToken(settings); // returns cookieValue by CookieName
    },

});

And in my routes.js, I intercept each request and check it.

// routes.js
router.beforeEach(async (to, from, next) => {
  const guarded = ['user', 'upload'];

  if (guarded.filter(i => i == to.name).length > 0) { 
    // guarded
    const t = await access.getToken()
    
    if (t == '') {
      // no token found in cookie
      next();
      return router.push({ name: 'login' });
    }
  } 
  
  next();
});

It works so far. But I wonder if this is a good solution because I'm just checking if the cookie has content. That means if I insert an arbitrary string into the cookie I would bypass this condition. Of course I wouldn't get any data from the server because the JWT would be wrong but still I wonder if there is a better solution?

Max Pattern
  • 1,430
  • 7
  • 18
  • You can expose an endpoint on the backend that verifies the JWT, something like `/auth/verify`. Within the endpoint, you look for the cookie, ensure it was signed/created with your private key. If it passes they check, the user is allowed access, otherwise you can reject and reroute the user to the Homepage. – lux Sep 12 '22 at 15:28
  • JWT is supposed to be valid. Decode it and check `exp` and possibly user access – Estus Flask Sep 12 '22 at 15:32
  • @lux that sounds good. however, frontend and backend are running on two different domains. therefore, the server-side verification would fail. But thank you very much! if it were the same origin then this would probably be a good solution. – Max Pattern Sep 12 '22 at 15:32
  • @lux There may be uses for such endpoint but generally it's orthogonal to what JWT offers. The relevant info is already stored in JWT – Estus Flask Sep 12 '22 at 15:33
  • @EstusFlask i cant decode the jwt in frontend. – Max Pattern Sep 12 '22 at 15:34
  • No, you can. You can't encode them, at least you shouldn't – Estus Flask Sep 12 '22 at 15:35
  • @EstusFlask i cant decode the jwt in frontend because to decode a JWT i need the secret. And it is not recomended to store the secret in the frontend. or am I wrong? – Max Pattern Sep 12 '22 at 15:37
  • 1
    Yes, you are wrong. It's asymmetrical. JWT isn't just glorified session cookie. It serves the exact purpose you need, you create it on backend and can read it at frontend and check when it expires, but you can't create a fake one on frontend. You can see it yourself, http://calebb.net/ – Estus Flask Sep 12 '22 at 15:40
  • @EstusFlask You are right! And it also makes sense that it is like that. I'm going to google now how to read out a jwt with JS. Then I would have the answer of my question!? (i hope :-)). Because if I can read out the info, then at least it's a valid jwt. Thank you very much! – Max Pattern Sep 12 '22 at 15:43
  • Small note: this would the function where you can decode your jwt: https://stackoverflow.com/a/38552302/18066399 – Max Pattern Sep 12 '22 at 15:47
  • Yes. Also you need to track 401/403 errors from all backend requests that are expected if JWT is invalid. User time could be wrong, so `exp` check on client side will pass, but will fail at backend – Estus Flask Sep 12 '22 at 15:49
  • @EstusFlask Is this answer incorrect? https://stackoverflow.com/a/46133159/894065 Seems that decoding on the FE is of course possible, but verification should happen server-side? Just trying to better understand this myself! My understanding has been shaken :-) – lux Sep 12 '22 at 15:49
  • 2
    It's correct. You can detect that a user is logged out by checking JWT `exp`, but you need to verify JWT on server side as well to check current auth state when API requests are done. – Estus Flask Sep 12 '22 at 15:53
  • @lux As I understand it, there is a residual risk on the client side. Because "a bad person" could replace the jwt token with any jwt token. The frontend cannot read the signature without the secret. On the frontend side, only the payload is possible to read out. this is probably why the link you posted does not require client-side validation. But as mentioned in my question. As soon as he tries to get content from the backend with the manipulated JWT, the "swindle/scam" will be exposed. – Max Pattern Sep 12 '22 at 15:55

0 Answers0