Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
282 views
in Technique[技术] by (71.8m points)

javascript - after axios interceptors return on error res is undefined

Hello I'm making a Reactjs app (with laravel backend) that uses jwt tokens to authenticate. I want to refresh the jwt token when the token has expired or is invalid (401 response). But the response is undefined in the show function when it goes through the error inteceptor.

(axios request function)

    show() {
        axios.get("/api/company/show/" + this.props.user.company_id)
        .then(res => {
            console.log(res)
            const company = res.data
            this.setState({
                company
            })
        }).catch(err => {
            console.log(err)
        })
    }

(interceptor response)

axios.interceptors.response.use(
  (response) => {
      console.log(response)
    return response
  },
...

if the token is valid the request returns a normal response and it works,

but when laravel returns a 401 error it does not work.

(laravel)

    public function handle($request, Closure $next)
    {
        try {
            $user = JWTAuth::parseToken()->authenticate();
        } catch (Exception $e) {
            if ($e instanceof TymonJWTAuthExceptionsTokenInvalidException) {
                return response()->json(['error' => 'Token is Invalid.'], 401);
            } else if ($e instanceof TymonJWTAuthExceptionsTokenExpiredException) {
                return response()->json(['error' => 'Token has Expired.'], 401);

            } else {
                return response()->json(['error' => 'Authorization Token not found.'], 401);
            }
        }
        return $next($request);
    }

(interceptor error)

...
  (error) => {
      console.log('error')
    return new Promise((resolve) => {
      const originalRequest = error.config
      console.log(originalRequest.headers.Authorization)
      const refreshToken = localStorage.getItem('token')
      if (error.response && (error.response.status === 401 || error.response.status===500) && error.config && !error.config.__isRetryRequest && refreshToken) {
        originalRequest._retry = true

        const response = fetch(process.env.REACT_APP_PUBLIC_PATH+'api/auth/refresh', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'Authorization': `Bearer ${refreshToken}`
          },
          body: JSON.stringify({
            refresh: refreshToken,
          }),
        })
          .then((res) => res.json())
          .then(res=>{
            console.log(res.token)
            localStorage.setItem("token", res.token)
            axios.defaults.headers.common["Authorization"] = `Bearer ${res.token}`
            originalRequest.headers.Authorization = `Bearer ${res.token}`
            return axios(originalRequest)
            })
        resolve(response)
      }

      return Promise.reject(error)
    }).then(()=>console.log('done refreshing'));
  },
)

The interceptor error will request a new token. Then the original call will be requested again with the new token. The new request response is visible in the interceptor (response) => {...} but not in the show() function

console.log first line is the console.log in the interceptor (response) third line is the console.log in the show() function and the error is that it can't find 'data' const company = res.data in the show() function

So the problem is that if I get a 401 error the request is undefined in the show() function (and other function to)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
等待大神答复

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...