Recent searches


No recent searches

Receive error 401 unauthorized when login with web widget



Posted Jun 24, 2022

I want to authenticate the user with zendesk so he will not have to type is name or anything. So I had the widget to my web site and after login I create a JWT and log the user to zendesk using the code bellow.

But, when I send the JWT I receive an error that my JWT is invalid but I have followed the format defined in the documentation.

Enabling authenticated visitors in the Chat widget – Zendesk help

    • error{code: "invalid_auth", description: "Invalid JWT"}
      • code"invalid_auth"
      • description"Invalid JWT"

I use c# backend to generate a JWT with the JWT.Net nuget package.

I use the plain secret genereted from zendesk. Do I need to base64 the secret before creating the JWT or i should use it as it is?

public class JwtTokenService
    {
        public string Secret { get; }

        public JwtTokenService(string secret)
        {
            Secret = secret;
        }
        
        public string Create()
        {
            var headers = new Dictionary<string, object> {
                { "typ", "JWT" },
                { "kid", "app_62b5e0ffca5a3800f0225c53" }
            };

            var payload = new Dictionary<string, object> {
                { "external_id", "12316542344" },
                { "email", "janes@soap.com" },
                { "exp", "12345678" },
                { "name", "Jane Soaps" },
                { "scope", "user" }
            };
            
            var alg = new HMACSHA256Algorithm();
            
            IJsonSerializer serializer = new JsonNetSerializer();
            IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
            IJwtEncoder encoder = new JwtEncoder(alg, serializer, urlEncoder); 
            return encoder.Encode(headers, payload, Secret);
        }
    }


In my web page I use the web widget sniped from copied from zendesk and I call the login.

<body>

<script id="ze-snippet" src="https://static.zdassets.com/ekr/snippet.js?key=....."> </script>

<script type="text/javascript">

  var jwt = "<%= SessionContext.Current.Jwt %>";


  zE('messenger', 'loginUser', function (callback) {
    callback(jwt);
  });

---

var jwt = "eyJ0eXAiOiJKV1QiLCJraWQiOiJhcHBfNjJiNWUwZmZjYTVhMzgwMGYwMjI1YzUzIiwiYWxnIjoiSFMyNTYifQ.eyJleHRlcm5hbF9pZCI6IjEyMzE2NTQyMzQ0IiwiZW1haWwiOiJqYW5lc0Bzb2FwLmNvbSIsImV4cCI6IjEyMzQ1Njc4IiwibmFtZSI6IkphbmUgU29hcHMiLCJzY29wZSI6InVzZXIifQ.ShaKIlanfmUoRqDpEvUEJkyJr6rdY9sUf1YckVAmddQ";
  
  zE('messenger', 'loginUser', function (callback) {
    callback(jwt);
  });

 

I have tested my JWT value in https://jwt.io/ and the JWT look good and the validation is ok.

 

I'm not sure what is the problem and where to look for any cues.

---

"eyJ0eXAiOiJKV1QiLCJraWQiOiJhcHBfNjJiNWUwZmZjYTVhMzgwMGYwMjI1YzUzIiwiYWxnIjoiSFMyNTYifQ.eyJleHRlcm5hbF9pZCI6IjEyMzE2NTQyMzQ0IiwiZW1haWwiOiJqYW5lc0Bzb2FwLmNvbSIsImV4cCI6IjEyMzQ1Njc4IiwibmFtZSI6IkphbmUgU29hcHMiLCJzY29wZSI6InVzZXIifQ.ShaKIlanfmUoRqDpEvUEJkyJr6rdY9sUf1YckVAmddQ"


2

13

13 comments

I am having the same issue.

Any help?

2


Check that your token is not expired. The "exp" field is specified in seconds since the UNIX epoch, so a token with exp = 12345678 expired sometime around February 1971. In TypeScript with the jsonwebtoken library, you could do something like:

import jwt, { SignOptions } from "jsonwebtoken";
const header = {
alg:"HS256",
typ:"JWT",
kid:zenDeskKid,
};

const options: SignOptions = {
header,
expiresIn: 60 * 60 * 6, // <-- this will convert to UNIX epoch time
};

const payload = {
scope:"user",
name: ...,
email: ... ,
external_id: ...,
};

var token = jwt.sign(payload, zenDeskSecret, options);

0


Also having a similar issue but mine says "JWT is malformed". Checked the timestamp in mine because of the reply above, but it's correct, like the rest of the JWT seems to be. 

1


Manuel Moreira did you try parsing your JWT and confirming it is properly formed? Try copy/pasting your JWT into https://jwt.io to make sure it is valid.

0


Dane Wheeler I have and yes it is valid

1


Manuel Moreira this sounds like a different issue than an expired JWT. For reference, below is what a working JWT looks like for my app. Perhaps you can compare yours to it to confirm you have the right header, field names, and data types.

0


Dane Wheeler it looks just like mine, so I have no idea what it could be

1


I have the same problem. All as in Zendesk docs and JSON Web Tokens - jwt.io shows that all is correct.

1


Anastasiia Kalugina check if you are sending the token with quotation marks.it should not be sent with quotes

0


Hi Manuel Moreira,

Thanks for you response.
What do you mean "with quotes"?

For example, in JavaScript I have:

const token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImFwcF82NDRhMjMwYWRhZDg4MjliMWM1NmQ0ZjgifQ.eyJleHRlcm5hbF9pZCI6MSwic2NvcGUiOiJ1c2VyIiwiaWF0IjoxNjgyNTg3NzA5fQ.ICzTP9maSQQVX0xjEPyzou8IjAzhkPIqDLdkgZ3Q98Q'

And I use it as argument in window.zE('messenger', 'loginUser', function(callback) {
    callback(token);
})


1


Anyone experiencing a similar problem, please read this article Enabling authenticated visitors in Web Widget (Classic) – Zendesk help. I have found that the messaging widget has similar features. Expiration time of token must be within 7 minutes and you should rotate it before its expiration time.

0


hey any update on this, find same issues, will zendesk official give help here?

 

0


image avatar

Tipene Hughes

Zendesk Developer Advocacy

Hey, ahsanu amala!

Can you send through an example of the headers and payload you're using to generate generate the JWT? Be sure to redact any sensitive information.

Can you also confirm that the shared_secret and KID you're using are accurate, and being passed correctly (KID in headers, shared_secret in jwt.sign method payload if you're using JS)

0


Please sign in to leave a comment.

Didn't find what you're looking for?

New post