GetStream/stream-video-js

How to refresh user jwt token?

efstathiosntonas opened this issue · 2 comments

Which package/packages do you use?

  • @stream-io/video-react-sdk
  • @stream-io/video-react-native-sdk
  • @stream-io/video-client

Describe the bug
I have this hook:

import { useCallback, useEffect, useState } from "react";

import { ApolloClient, NormalizedCacheObject, useApolloClient } from "@apollo/client";
import { StreamVideoClient } from "@stream-io/video-react-native-sdk";
import * as SecureStore from "expo-secure-store";
import Keys from "react-native-keys";

import { currentUser } from "@functions/auth";

import { deviceModel } from "@utils/utils";

import { GetStreamTokenDocument } from "@generated/graphql";

// Define the hook
function useStreamClient() {
  const client = useApolloClient() as ApolloClient<NormalizedCacheObject>;
  const userId = currentUser().uid;
  const [streamClient, setStreamClient] = useState<StreamVideoClient | undefined>();

  const tokenProvider = useCallback(async () => {
    const { data } = await client.query({
      query: GetStreamTokenDocument,
      fetchPolicy: "no-cache"
    });
    return data.get_stream_token.token;
  }, [client]);

  useEffect(() => {
    let isSubscribed = true; // To avoid setting state on unmounted component

    (async () => {
      const token = await tokenProvider();
      const myClient = new StreamVideoClient({
        apiKey: Keys.secureFor("STREAM_API_KEY"),
        token,
        user: {
          id: userId,
          name: deviceModel 
        }
        // options: {
        //   logLevel: "info"
        // }
      });

      if (isSubscribed) {
        setStreamClient(myClient);
        SecureStore.setItemAsync("stream_token", token);
      }

      return () => {
        if (isSubscribed) {
          myClient.disconnectUser();
          setStreamClient(undefined);
        }
      };
    })();

    return () => {
      isSubscribed = false;
    };
  }, [client, tokenProvider, userId]);

  return streamClient;
}

export default useStreamClient;

usage:

  const client = useStreamVideoClient();

  const onPressVideoCall = useCallback(() => {
      if (client) {
        client.call("development", nanoid(10)).getOrCreate({
          ring: true,
          data: {
            members: [{ user_id: currentUser().uid }, { user_id: targetProfile.id }]
          }
        });
      }

  }, [channel, client]);

User does not close or move away from the app, when the token expires after one hour, I get 401 error when tapping the call button. How to make sure the token is always refreshed? I know we can manually set the expiration time on the jwt but I want to keep it in 1hr as all of my other jwt tokens.

Shouldn't the code handle this automatically for us?

Version

  • SDK versionL 0.6.11

Hi @efstathiosntonas,

You should pass the tokenProvider to the StreamVideoClient constructor as described here:

Can you update your code like this?

const myClient = new StreamVideoClient({
  apiKey: Keys.secureFor("STREAM_API_KEY"),
  tokenProvider, // this used to be 'token'
  user: {
    id: userId,
    name: deviceModel 
  }
  // options: {
  //   logLevel: "info"
  // }
});

@oliverlaz thanks for the quick reply!

Nice catch there! Now it should auto refresh it, thanks!

needed the token for the SecureStore so it fell through in the client config!