0

I have a code that decodes JWT tokens, splits the string part that contains claims and converts that info into a JSON object.

return JSON.parse(atob(token.split('.')[1])) as LoggedInUser;

It works but when it comes to user's name, since it has some turkish characters, I get a string with non-readable characters. User's name is "Uğur Gül" in the picture below.

wrongly formatted json object

I think I should somehow parse with utf-8 formatting but can't find how to that. I'm working with angular framework. How can I fix this issue?

Edit: Here is a decoded version of my mock-data token on jwt.io. I'm trying to get the payload from token like the way jwt.io creates an JSON object, and I'm assigning needed values to related fields to an instance of LoggedInUser class.

jwt.io decoded version

4
  • 1
    The data comes from a backend? Please show me the token data before parsing. Commented Dec 26, 2022 at 8:29
  • @Flo Yes, data comes from backend. Just edited my question. You can check the example data it contains. Token comes from backend is a long string like this one: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c" I'm getting the part after first dot. That's payload part. Commented Dec 26, 2022 at 8:41
  • 1
    that's "John Doe", show us "Uğur Gül" Commented Dec 26, 2022 at 8:54
  • @Flo here is one with "Uğur Gül" "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOiIyIiwiVXNlckdpdmVuTmFtZSI6IlXEn3VyIEfDvGwiLCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3JvbGUiOiIyIiwiZXhwIjoxNjcyMDQ2Mzc1LCJpc3MiOiJodHRwczovL2xvY2FsaG9zdDo3MDEzLyIsImF1ZCI6Imh0dHBzOi8vbG9jYWxob3N0OjcwMTMvIn0.EERKwS2yfT6TnPJN4zlHyvW4WhrEMmaFLpUh0r8Ej70" Commented Dec 26, 2022 at 9:05

1 Answer 1

-2

One way is to escape and unescape the name on the backend/frontend. I don't know how your app works.

We use escape and Uğur Gül will converted to U%u011Fur%20G%FCl. Set this to GivenUserName, create the token and send it to the frontend. Frontend decodes it, gave the name and call unescape. So you have the correct name again.

Sample:

data = '{"UserId":"2","UserGivenName":"U%u011Fur%20G%FCl","http://schemas.microsoft.com/ws/2008/06/identity/claims/role":"2","exp":1672046375,"iss":"https://localhost:7013/","aud":"https://localhost:7013/"}'

  constructor() {
    console.log((escape("Uğur Gül")));
    console.log(unescape(escape("Uğur Gül")))

    this.token = (btoa(this.data))
    const jsonData = JSON.parse(atob(this.token));
    console.log(unescape(jsonData.UserGivenName));
  }

Important

escape and unescape are marked as deprecated. You can use encodeURI and decodeURI instead:

    console.log(encodeURI('Uğur Gül'));
    console.log(decodeURI(encodeURI('Uğur Gül')));

Here is a Stackblitz to play.

Sign up to request clarification or add additional context in comments.

5 Comments

Not only shouldn't this be necessary, escape is also on the list of deprecated functions you shouldn't use.
Look at updated Post
Better, but it still doesn't work if you're given a UTF-8 encoded string by a 3rd party which you need to deal with.
Then we need to see the backend code, which encode the string. Without it this is a working solution.
As provided in the sample, the backend provides a perfectly fine UTF-8 encoded JWT. It's a known "issue" in JS that decoding base64 containing UTF-8 encoded text to a string is… tricky. I closed this question as a duplicate…

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.