14

I am new to flutter and I am using http package for network call. I want to refresh token and call the request again if the response code of the request 200. How can I acheive this using http package? I heard about dio package but it is complicated for me.

User getUser(){

   final response = http.post(Uri.https(BASE_URL, '/api/user'), 
    headers: {'Authorization: Bearer $token'});

    if(response.statusCode == 200){
       return User.fromJson(jsonDecode(response.body)['user']);
    }
    else if(response.statusCode == 401){
      //refresh token and call getUser again     
    }

}
techno
  • 141
  • 1
  • 1
  • 3
  • 1
    use interceptor to retry your request. may this package helps you:- https://pub.dev/packages/http_interceptor – Ravi Sevta Apr 25 '21 at 14:26
  • when the token expires, it should give a response code 401. In this case you can call a new function to get a fresh token and replace the old token with the response received. – Ujjwal Raijada Apr 27 '21 at 14:55

3 Answers3

22

You can use refresh token as follows:

User getUser(){

   final response = http.post(Uri.https(BASE_URL, '/api/user'), 
    headers: {'Authorization: Bearer $token'});

    if(response.statusCode == 200){
       return User.fromJson(jsonDecode(response.body)['user']);
    }
    else if(response.statusCode == 401){
      //refresh token and call getUser again
      final response = http.post(Uri.https(BASE_URL, '/api/[YourAuthorizationEndpoint]'), 
    headers: {'grant_type': 'refresh_token', 'refresh_token': '$refresh_token'});
      token = jsonDecode(response.body)['token'];
      refresh_token = jsonDecode(response.body)['refresh_token'];
      return getUser();
    }

}
serkanayaz
  • 745
  • 6
  • 20
  • 6
    Error 401 is for Un-authorize, but it does not only means that the Token is expired. What if the Token is not expired BUT the user is not authorized to access the resources due to some other reasons? Then what strategy should be applied to know if 401 was returned due to Token expiry or some other reason? – Naveed Jamali Nov 25 '21 at 15:21
  • You have access to the `response.body` so you can examine it to check the response. Then you would just modify the code to check for the body response criteria. – Jeremy Dec 01 '21 at 23:18
  • 6
    What about when the refresh endpoint also returns Unauthorized 401? that'll be an infinite loop – Lemayzeur Jan 19 '22 at 02:09
10

You can use dart's http/retry package:

import 'package:http/http.dart' as http;
import 'package:http_retry/http_retry.dart';

final client = RetryClient(
   http.Client(), 
   retries: 1,
   when: (response) {
    return response.statusCode == 401;
   },
   onRetry: (req, res, retryCount) {
     if (retryCount == 0 && res?.statusCode == 401) {
        // refresh token
     }  
   },
);

try {
  final response = await client.get('http://www.example.com');
} finally {
  client.close();
}
aabiro
  • 3,842
  • 2
  • 23
  • 36
  • `return response.statusCode == 401 ? true : false` => `return response.statusCode == 401`... – genericUser Jul 17 '22 at 13:29
  • 1
    line 8 is a masterpiece. teach me master :D – stackunderflow Sep 22 '22 at 21:27
  • Iam Trying this and the token is refreshed indeed, but the request itself is still using the old JWT and the response is still 401 as if it was the old request result and the JWT in the header value does not update....how to solve this? – Emam Dec 31 '22 at 23:25
4

call an api to refresh token after expiration

you can use this [package][1]

[1]: https://pub.dev/packages/jwt_decoder to check if token is expired

you can also get the time since token created and date of expiration

kururu
  • 43
  • 5