Search code examples
androidjwtzendeskzendesk-sdk

Zendesk SDK JwtAuthentication not working


I have the SDK for android and I try to setup JWT Identity for chat and support modules.

I have a webhook defined as in the doc. It work. I see in the log that zendesk is sending the user token I give him in the JwtIdentity and it returns a jwt as specified in the doc with name, email, jti and iat.

Code of the webhook :

router.post('/jwt', async (req, res, next) => {
    try {
        console.log(req.body)
        const user_token = req.body.user_token

        const user = await usersService.findByTokend(user_token)

        if (typeof user === "undefined" || user === null) {
            return res.status(404).send('No user found').end()
        }

        const token = jwt.sign({
                name: `${user.lastname} ${user.firstname}`.toLowerCase().trim(),
                email: user.email.toLowerCase().trim(),
            },
            JWT_SECRET,
            {
                expiresIn: '12h',
                jwtid: uuidv4()
            })

        console.log(token)
        return res.status(200).send({
            jwt: token
        }).end()
    } catch (err) {
        console.log(err)
        next(err)
    }
})

Nothing goes wrong in the log of my webhook and in my SDK implementation during initialisation. It's when I call the activity and it try to authenticate the user that it fail.

For chat instance I have defined a JwtAuthenticator as follow :

public class ZendeskJwtAuthenticator implements JwtAuthenticator {
    private String user_token;

    public void setUserToken(String user_token) {
        this.user_token = user_token;
    }

    @Override
    public void getToken(JwtCompletion jwtCompletion) {
        try {
            OkHttpClient client = new OkHttpClient();
            
            JSONObject jsonBody = new JSONObject();
            jsonBody.put("user_token", user_token);

            RequestBody requestJsonBody = RequestBody.create(
                    jsonBody.toString(),
                    MediaType.parse("application/json")
            );

            Request postRequest = new Request.Builder()
                    .url(url)
                    .post(requestJsonBody)
                    .build();

            client.newCall(postRequest).enqueue(new Callback() {
                @Override
                public void onFailure(@NotNull Call call, @NotNull IOException e) {
                    jwtCompletion.onError();
                }

                @Override
                public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                    try {
                        String body = response.body().string();
                        JsonObject jsonObject = JsonParser.parseString(body).getAsJsonObject();
                        if (jsonObject.has("jwt")) {
                            jwtCompletion.onTokenLoaded(jsonObject.get("jwt").getAsString());
                        } else {
                            jwtCompletion.onError();
                        }
                    } catch (Exception e) {
                        jwtCompletion.onError();
                    }
                }
            });
        } catch (Exception exception) {
            jwtCompletion.onError();
        }
    }
}

I call set identity as follow :

private void setUserIdentity(String user_token) {
    Identity identity = new JwtIdentity(user_token);
    ZendeskJwtAuthenticator autenticator = new ZendeskJwtAuthenticator();
    autenticator.setUserToken(user_token);
    Zendesk.INSTANCE.setIdentity(identity);
    Chat.INSTANCE.setIdentity(autenticator);
}

It is called after init :

Zendesk.INSTANCE.init(appContext, zendeskUrl, appId, clientId);
Chat.INSTANCE.init(appContext, chatKey, chatAppId);
Support.INSTANCE.init(Zendesk.INSTANCE);
this.setUserIdentity(options);

In the log I have that when I open chat :

I/okhttp.OkHttpClient: --> POST https://id.zopim.com/authenticated/web/jwt (318-byte body)
I/ReactNativeJNI: Memory warning (pressure level: TRIM_MEMORY_RUNNING_CRITICAL) received by JS VM, running a GC
I/okhttp.OkHttpClient: <-- 400 https://id.zopim.com/authenticated/web/jwt (2412ms, 63-byte body)
W/JwtLoginDetailsProvider: Error fetching authentication token. There may be an issue with your JWT. Chat will proceed unauthenticated: 400

And when I open help center :

I/okhttp.OkHttpClient: --> GET https://<company>.zendesk.com/hc/api/mobile/fr/article_tree.json?category_ids=&section_ids=&include=categories%2Csections&limit=5&article_labels=&per_page=1000&sort_by=created_at&sort_order=desc
I/okhttp.OkHttpClient: --> POST https://<company>.zendesk.com/access/sdk/jwt (22-byte body)
I/okhttp.OkHttpClient: <-- 403 https://<company>.zendesk.com/access/sdk/jwt (3350ms, unknown-length body)
I/okhttp.OkHttpClient: <-- 400 Response body was null, failed to auth user. https://<company>.zendesk.com/hc/api/mobile/fr/article_tree.json?category_ids=&section_ids=&include=categories%2Csections&limit=5&article_labels=&per_page=1000&sort_by=created_at&sort_order=desc (3359ms, 2-byte body)

Solution

  • I got the solution and post-it if someone comme here with the same issue.

    I fact, I have indeed all well configured and working. My Only mistake is that I used the same email to identify my in app customer and my zendesk admin.

    That's all. Have a good day.