# Twitch Extension Authentication via JWT and shared secret

**URL:** <https://staging-discuss.dev.twitch.com/t/twitch-extension-authentication-via-jwt-and-shared-secret/35454>\
**Category:** API\
**Created:** [December 17, 2021, 12:17pm UTC](https://staging-discuss.dev.twitch.com/t/twitch-extension-authentication-via-jwt-and-shared-secret/35454 "2021-12-17T12:17:34Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![peterugah](https://d1d6mrmdu7ztse.cloudfront.net/user_avatar/staging-discuss.dev.twitch.com/peterugah/32/15760_2.png) [@peterugah](https://staging-discuss.dev.twitch.com/u/peterugah)\
**Post date:** [December 17, 2021, 12:17pm UTC](https://staging-discuss.dev.twitch.com/t/twitch-extension-authentication-via-jwt-and-shared-secret/35454/1 "2021-12-17T12:17:34Z")

</div>

Hi,  
I followed the guide [here](https://dev.twitch.tv/docs/tutorials/extension-101-tutorial-series/jwt) to authenticating my extension against my backend, but each time i do i get the error  
“JsonWebTokenError: invalid signature”  
I’ve created the shared secret, decoded it and used it to verify the token i received from my extension but still get the same error.  
please see my code below for reference.  
An assistance in fixing this asap will go a long way, as this has delayed our extension development.

```auto
  req: Request,
  res: Response,
  next: NextFunction,
): Promise<unknown> => {
  try {
    const { authorization } = req.headers;
    const splits = authorization.split(' ');

    const clientSecret = process.env.TWITCH_CLIENT_SECRET;
    const clientId = process.env.TWITCH_CLIENT_ID;

    if (!clientId || !clientSecret) {
      return GenericResponses.errorResponse(
        res,
        GenericResponses.INVALID_TWITCH_TOKEN(),
      );
    }

    if (splits[0] !== 'Bearer' || !splits[1]) {
      return GenericResponses.errorResponse(res, GenericResponses.INVALID_TWITCH_TOKEN());
    }
    const token = splits[1];

    const base64DecodedToken = Buffer.from(clientSecret, 'base64');

    defaultLogger.error(clientSecret);
    defaultLogger.error(base64DecodedToken);

    // TODO: if token is expired, return an error here too
    jwt.verify(token, base64DecodedToken, { algorithms: ['HS256'] });

    return next();
  } catch (e) {
    defaultLogger.error('error is ', e);
    return GenericResponses.errorResponse(res, ApiAccessResponses.UNAUTHORISED());
  }
};
```

---

<div class="post-metadata">

**Author:** ![BarryCarlyon](https://d1d6mrmdu7ztse.cloudfront.net/user_avatar/staging-discuss.dev.twitch.com/barrycarlyon/32/253_2.png) [@BarryCarlyon](https://staging-discuss.dev.twitch.com/u/BarryCarlyon)\
**Post date:** [December 17, 2021, 12:20pm UTC](https://staging-discuss.dev.twitch.com/t/twitch-extension-authentication-via-jwt-and-shared-secret/35454/2 "2021-12-17T12:20:45Z")

</div>

> [@peterugah](#):
>
> ` const clientSecret = process.env.TWITCH_CLIENT_SECRET;`

You used the wrong secret. based on the name

You need the Extension secret not the client secret  
The bottom key not the top API Client Secret: in this screenshot

 ![image](https://d2spem0quai2ol.cloudfront.net/original/2X/a/aaf5141efbb0c040f5efc5fb0f23a5c07cf087b1.png)

---

<div class="post-metadata">

**Author:** ![peterugah](https://d1d6mrmdu7ztse.cloudfront.net/user_avatar/staging-discuss.dev.twitch.com/peterugah/32/15760_2.png) [@peterugah](https://staging-discuss.dev.twitch.com/u/peterugah)\
**Post date:** [December 17, 2021, 12:24pm UTC](https://staging-discuss.dev.twitch.com/t/twitch-extension-authentication-via-jwt-and-shared-secret/35454/3 "2021-12-17T12:24:20Z")

</div>

actually the name is wrong, but that is the value stored in that env variable.

---

<div class="post-metadata">

**Author:** ![BarryCarlyon](https://d1d6mrmdu7ztse.cloudfront.net/user_avatar/staging-discuss.dev.twitch.com/barrycarlyon/32/253_2.png) [@BarryCarlyon](https://staging-discuss.dev.twitch.com/u/BarryCarlyon)\
**Post date:** [December 17, 2021, 12:26pm UTC](https://staging-discuss.dev.twitch.com/t/twitch-extension-authentication-via-jwt-and-shared-secret/35454/4 "2021-12-17T12:26:13Z")

</div>

Then as long as you copied and pasted the entire thing. (sometimes a copy/paste will miss characters if not quite paying attention)

And your frontend passed up the correct token (the authToken not the helixToken)

Then the other thing to do is to check that the recieved variables on your server are what you expect.  
And check the time on the recieving server is accurate.

After that theres not many other things it could be unless you have a second extension and loaded in the wrong extension secret

---

<div class="post-metadata">

**Author:** ![peterugah](https://d1d6mrmdu7ztse.cloudfront.net/user_avatar/staging-discuss.dev.twitch.com/peterugah/32/15760_2.png) [@peterugah](https://staging-discuss.dev.twitch.com/u/peterugah)\
**Post date:** [December 17, 2021, 12:27pm UTC](https://staging-discuss.dev.twitch.com/t/twitch-extension-authentication-via-jwt-and-shared-secret/35454/5 "2021-12-17T12:27:22Z")

</div>

> [@peterugah](#):
>
> he value stored in that env variable.

ADMIN: REMOVED LEAKED SECRET

---

<div class="post-metadata">

**Author:** ![BarryCarlyon](https://d1d6mrmdu7ztse.cloudfront.net/user_avatar/staging-discuss.dev.twitch.com/barrycarlyon/32/253_2.png) [@BarryCarlyon](https://staging-discuss.dev.twitch.com/u/BarryCarlyon)\
**Post date:** [December 17, 2021, 12:27pm UTC](https://staging-discuss.dev.twitch.com/t/twitch-extension-authentication-via-jwt-and-shared-secret/35454/6 "2021-12-17T12:27:59Z")

</div>

Please do not leak your secret!

---

<div class="post-metadata">

**Author:** ![peterugah](https://d1d6mrmdu7ztse.cloudfront.net/user_avatar/staging-discuss.dev.twitch.com/peterugah/32/15760_2.png) [@peterugah](https://staging-discuss.dev.twitch.com/u/peterugah)\
**Post date:** [December 17, 2021, 12:30pm UTC](https://staging-discuss.dev.twitch.com/t/twitch-extension-authentication-via-jwt-and-shared-secret/35454/7 "2021-12-17T12:30:00Z")

</div>

its a demo extension for test purposes i was going to delete anyways.  
but thanks noted.

---

<div class="post-metadata">

**Author:** ![BarryCarlyon](https://d1d6mrmdu7ztse.cloudfront.net/user_avatar/staging-discuss.dev.twitch.com/barrycarlyon/32/253_2.png) [@BarryCarlyon](https://staging-discuss.dev.twitch.com/u/BarryCarlyon)\
**Post date:** [December 17, 2021, 12:31pm UTC](https://staging-discuss.dev.twitch.com/t/twitch-extension-authentication-via-jwt-and-shared-secret/35454/8 "2021-12-17T12:31:03Z")

</div>

> [@peterugah](#):
>
> its a demo extension for test purposes i was going to delete anyways.

if you delete it liekly will not release the name to the pool to be used.

So you should just hang on to it rather than delete!

or use it for further testing

---

<div class="post-metadata">

**Author:** ![peterugah](https://d1d6mrmdu7ztse.cloudfront.net/user_avatar/staging-discuss.dev.twitch.com/peterugah/32/15760_2.png) [@peterugah](https://staging-discuss.dev.twitch.com/u/peterugah)\
**Post date:** [December 17, 2021, 12:31pm UTC](https://staging-discuss.dev.twitch.com/t/twitch-extension-authentication-via-jwt-and-shared-secret/35454/9 "2021-12-17T12:31:42Z")

</div>

ok.  
So, how do i resolve this issue with authentication?

---

<div class="post-metadata">

**Author:** ![BarryCarlyon](https://d1d6mrmdu7ztse.cloudfront.net/user_avatar/staging-discuss.dev.twitch.com/barrycarlyon/32/253_2.png) [@BarryCarlyon](https://staging-discuss.dev.twitch.com/u/BarryCarlyon)\
**Post date:** [December 17, 2021, 12:32pm UTC](https://staging-discuss.dev.twitch.com/t/twitch-extension-authentication-via-jwt-and-shared-secret/35454/10 "2021-12-17T12:32:24Z")

</div>

> [@BarryCarlyon](#):
>
> And your frontend passed up the correct token (the authToken not the helixToken)
> 
> Then the other thing to do is to check that the recieved variables on your server are what you expect.  
> And check the time on the recieving server is accurate.
> 
> After that theres not many other things it could be unless you have a second extension and loaded in the wrong extension secret

Did you check/try these other steps?

---

<div class="post-metadata">

**Author:** ![peterugah](https://d1d6mrmdu7ztse.cloudfront.net/user_avatar/staging-discuss.dev.twitch.com/peterugah/32/15760_2.png) [@peterugah](https://staging-discuss.dev.twitch.com/u/peterugah)\
**Post date:** [December 17, 2021, 12:34pm UTC](https://staging-discuss.dev.twitch.com/t/twitch-extension-authentication-via-jwt-and-shared-secret/35454/11 "2021-12-17T12:34:51Z")

</div>

I’ve checked all this. All seems fine

---

<div class="post-metadata">

**Author:** ![BarryCarlyon](https://d1d6mrmdu7ztse.cloudfront.net/user_avatar/staging-discuss.dev.twitch.com/barrycarlyon/32/253_2.png) [@BarryCarlyon](https://staging-discuss.dev.twitch.com/u/BarryCarlyon)\
**Post date:** [December 17, 2021, 12:36pm UTC](https://staging-discuss.dev.twitch.com/t/twitch-extension-authentication-via-jwt-and-shared-secret/35454/12 "2021-12-17T12:36:05Z")

</div>

Then I’m out of ideas.

Your logic matches what I run in production and matches (close enough) to what I have in this working example extension

> **[GitHub - BarryCarlyon/twitch\_profile\_extension: A simple Twitch Extension to...](https://github.com/barrycarlyon/twitch_profile_extension)**
>
> A simple Twitch Extension to cover the basics of using the JWT and EBS together to get Twitch API information - GitHub - BarryCarlyon/twitch\_profile\_extension: A simple Twitch Extension to cover th...

You can also try manually validating it using the Debugger on

> **[JWT.IO](https://jwt.io/)**
>
> JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.

---

<div class="post-metadata">

**Author:** ![peterugah](https://d1d6mrmdu7ztse.cloudfront.net/user_avatar/staging-discuss.dev.twitch.com/peterugah/32/15760_2.png) [@peterugah](https://staging-discuss.dev.twitch.com/u/peterugah)\
**Post date:** [December 17, 2021, 12:37pm UTC](https://staging-discuss.dev.twitch.com/t/twitch-extension-authentication-via-jwt-and-shared-secret/35454/13 "2021-12-17T12:37:26Z")

</div>

Ok, i’ll take a look at this. Thanks

---

<div class="post-metadata">

**Author:** ![system](https://d2spem0quai2ol.cloudfront.net/original/2X/0/05909729875cce3b53e59d5561c4d23bb14948fc.png) [@system](https://staging-discuss.dev.twitch.com/u/system)\
**Post date:** [January 16, 2022, 12:38pm UTC](https://staging-discuss.dev.twitch.com/t/twitch-extension-authentication-via-jwt-and-shared-secret/35454/14 "2022-01-16T12:38:22Z")

</div>

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.
