Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

135 linhas
4.7 KiB

  1. import axios from 'axios'
  2. import jwtDefaultConfig from './jwtDefaultConfig'
  3. export default class JwtService {
  4. // ** jwtConfig <= Will be used by this service
  5. jwtConfig = {...jwtDefaultConfig}
  6. // ** For Refreshing Token
  7. isAlreadyFetchingAccessToken = false
  8. // ** For Refreshing Token
  9. subscribers = []
  10. constructor(jwtOverrideConfig) {
  11. this.jwtConfig = {...this.jwtConfig, ...jwtOverrideConfig}
  12. // ** Request Interceptor
  13. axios.interceptors.request.use(
  14. config => {
  15. // ** Get token from localStorage
  16. const accessToken = this.getToken()
  17. // ** If token is present add it to request's Authorization Header
  18. if (accessToken) {
  19. // ** eslint-disable-next-line no-param-reassign
  20. config.headers.Authorization = `${this.jwtConfig.tokenType} ${accessToken}`
  21. }
  22. config.headers['X-Authorization'] = process.env.REACT_APP_API_KEY
  23. return config
  24. },
  25. error => Promise.reject(error)
  26. )
  27. // ** Add request/response interceptor
  28. axios.interceptors.response.use(
  29. response => response,
  30. error => {
  31. // ** const { config, response: { status } } = error
  32. const {config, response} = error
  33. const originalRequest = config
  34. const reqUrl = config?.url || ''
  35. // ** if (status === 401) {
  36. if (response && response.status === 401) {
  37. const isPublicAuthRequest =
  38. reqUrl.includes('/login') ||
  39. reqUrl.includes('/ldap-login') ||
  40. reqUrl.includes('/refresh-token')
  41. if (isPublicAuthRequest) {
  42. return Promise.reject(error)
  43. }
  44. if (!this.isAlreadyFetchingAccessToken) {
  45. this.isAlreadyFetchingAccessToken = true
  46. this.refreshToken()
  47. .then(r => {
  48. this.isAlreadyFetchingAccessToken = false
  49. // ** Update accessToken in localStorage
  50. this.setToken(r.data.accessToken)
  51. this.setRefreshToken(r.data.refreshToken)
  52. this.onAccessTokenFetched(r.data.accessToken)
  53. })
  54. .catch(refreshError => {
  55. this.isAlreadyFetchingAccessToken = false
  56. this.onAccessTokenFetchFailed(refreshError)
  57. })
  58. }
  59. const retryOriginalRequest = new Promise((resolve, reject) => {
  60. this.addSubscriber(
  61. accessToken => {
  62. // ** Make sure to assign accessToken according to your response.
  63. // ** Check: https://pixinvent.ticksy.com/ticket/2413870
  64. // ** Change Authorization header
  65. originalRequest.headers.Authorization = `${this.jwtConfig.tokenType} ${accessToken}`
  66. resolve(axios(originalRequest))
  67. },
  68. reject
  69. )
  70. })
  71. return retryOriginalRequest
  72. }
  73. return Promise.reject(error)
  74. }
  75. )
  76. }
  77. onAccessTokenFetched(accessToken) {
  78. this.subscribers.forEach(({ onSuccess }) => onSuccess(accessToken))
  79. this.subscribers = []
  80. }
  81. onAccessTokenFetchFailed(refreshError) {
  82. this.subscribers.forEach(({ onFailure }) => onFailure(refreshError))
  83. this.subscribers = []
  84. }
  85. addSubscriber(onSuccess, onFailure) {
  86. this.subscribers.push({ onSuccess, onFailure })
  87. }
  88. getToken() {
  89. return localStorage.getItem(this.jwtConfig.storageTokenKeyName)
  90. }
  91. getRefreshToken() {
  92. return localStorage.getItem(this.jwtConfig.storageRefreshTokenKeyName)
  93. }
  94. setToken(value) {
  95. localStorage.setItem(this.jwtConfig.storageTokenKeyName, value)
  96. }
  97. setRefreshToken(value) {
  98. localStorage.setItem(this.jwtConfig.storageRefreshTokenKeyName, value)
  99. }
  100. login(...args) {
  101. return axios.post(this.jwtConfig.loginEndpoint, ...args)
  102. }
  103. register(...args) {
  104. return axios.post(this.jwtConfig.registerEndpoint, ...args)
  105. }
  106. refreshToken() {
  107. return axios.post(this.jwtConfig.refreshEndpoint, {
  108. refreshToken: this.getRefreshToken()
  109. })
  110. }
  111. }