Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

90 rader
3.1 KiB

  1. import { createContext, useEffect, useRef, useCallback } from 'react';
  2. import { apiPath } from 'auth/utils';
  3. import { REFRESH_TOKEN } from 'utils/ApiPathConst';
  4. import axios from 'axios';
  5. import {
  6. isUserLoggedIn,
  7. } from "utils/Utils";
  8. const RefreshTokenContext = createContext();
  9. const RefreshTokenProvider = ({ children }) => {
  10. const token = useRef(localStorage.getItem('accessToken'));
  11. const isRefresh = useRef(false);
  12. // handle Refresh Token Logic
  13. const handleRefreshToken = useCallback(() => {
  14. if (!isRefresh.current) {
  15. const refreshToken = localStorage.getItem('refreshToken');
  16. isRefresh.current = true;
  17. axios
  18. .post(`${apiPath}${REFRESH_TOKEN}`, {
  19. refreshToken: refreshToken
  20. })
  21. .then((response) => {
  22. if (response.status === 200) {
  23. const newAccessToken = response.data.accessToken;
  24. const newRefreshToken = response.data.refreshToken;
  25. localStorage.setItem('accessToken', newAccessToken);
  26. localStorage.setItem('refreshToken', newRefreshToken);
  27. token.current = newAccessToken;
  28. isRefresh.current = false;
  29. } else {
  30. token.current = null;
  31. isRefresh.current = false;
  32. }
  33. })
  34. .catch((refreshError) => {
  35. console.log('Failed to refresh token');
  36. if (refreshError != undefined){
  37. console.log(refreshError)
  38. }
  39. token.current = null
  40. isRefresh.current = false;
  41. });
  42. }
  43. }, []);
  44. // Function to check token expiry
  45. const checkTokenExpiry = useCallback(() => {
  46. // Check if token is present and its expiry time
  47. if (token.current) {
  48. let tokenExp;
  49. try {
  50. // JWT payload is base64url; atob needs standard base64
  51. let payload = token.current.split('.')[1]
  52. .replace(/-/g, '+')
  53. .replace(/_/g, '/');
  54. payload += '='.repeat((4 - (payload.length % 4)) % 4);
  55. tokenExp = JSON.parse(atob(payload)).exp;
  56. } catch (e) {
  57. token.current = null;
  58. return;
  59. }
  60. const currentTime = Math.floor(Date.now() / 1000);
  61. const expiryTime = tokenExp - 30; // Refresh 30 seconds before expiry
  62. // console.log("check refresh Token");
  63. // console.log(currentTime);
  64. // console.log(new Date(currentTime*1000).toLocaleString());
  65. // console.log(expiryTime);
  66. // console.log(new Date(expiryTime*1000).toLocaleString());
  67. // console.log('accessToken: ' + localStorage.getItem('accessToken'));
  68. // console.log('refreshToken: ' + localStorage.getItem('refreshToken'));
  69. if (currentTime >= expiryTime) {
  70. if(isUserLoggedIn()){
  71. handleRefreshToken();
  72. }
  73. }
  74. }
  75. }, [token]);
  76. // Start the timer on component mount
  77. useEffect(() => {
  78. const timer = setInterval(checkTokenExpiry, 10000); // Check every 10 second
  79. return () => clearInterval(timer); // Cleanup timer on unmount
  80. }, [checkTokenExpiry]);
  81. return <RefreshTokenContext.Provider value={{}}>{children}</RefreshTokenContext.Provider>;
  82. };
  83. export { RefreshTokenContext, RefreshTokenProvider };