Dio Interceptor не работает по первому запросу в том же обратном вызове, только последующие вызовы

Я тестирую дио и пытаюсь добавить перехватчик, чтобы просто добавить токен к будущим запросам, но получаю странные результаты, которые я не могу исправить. Все, что у меня есть в качестве теста, это 2 кнопки. Одна при нажатии должна войти в систему и добавить токен к перехватчику, а вторая кнопка запрашивает данные профиля авторизации. По какой-то причине, нажав кнопку входа, я вхожу в систему нормально, но получаю 403 Forbidden при нажатии второй кнопки для доступа к данным профиля аутентификации (даже если я запрашиваю данные профиля после добавления перехватчика). Странно то, что когда я снова нажимаю вторую кнопку (без изменения кода или даже горячей перезагрузки), все работает нормально, и данные профиля авторизации распечатываются. Каждый раз при горячем перезапуске я возвращаюсь к той же проблеме, когда мой первый запрос данных профиля аутентификации имеет 403, но последующие запросы работают нормально. Я пытался понять, что происходит в течение пары часов, и не могу понять, что не так. Пожалуйста помоги. Спасибо. (Бэкэнд обрабатывается django, но проблема не может быть там, поскольку api работает с другими фреймворками, и даже в dio отлично работает при последующих нажатиях кнопок, но не при первом)

Код


class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  Dio session = Dio(
    BaseOptions(
      connectTimeout: 30000,
      baseUrl: 'http://127.0.0.1:8000',
      responseType: ResponseType.json,
      contentType: ContentType.json.toString(),
    ),
  );
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            RaisedButton(
                child: Text('Log In'),
                onPressed: () async {
                  print('starting');
                  var res = await session.post('/auth/login/',
                      data: {'username': 'tester', 'password': 'tester'});
                  print(res.data);
                  session.interceptors.clear();
                  session.interceptors.addAll([
                    InterceptorsWrapper(
                      onRequest: (RequestOptions requestOptions) {
                        session.interceptors.requestLock.lock();
                        String token = res.data['key'];
                        if (token != null) {
                          session.options.headers[HttpHeaders.authorizationHeader] =
                              ‘token $token’;
                        }
                        session.interceptors.requestLock.unlock();
                        return requestOptions;
                      },
                      onError: (e) => print(e.message),
                    ),
                  ]);
                  print(session.interceptors);
                }),
            RaisedButton(
                child: Text('Get Profile'),
                onPressed: () async {
                  session.get('/api/auth/').then((res) => print(res.data));
                }),
          ],
        ),
      ),
    );
  }
}

Консоль при нажатии кнопки входа в систему

Restarted application in 11,586ms.
flutter: starting
flutter: {key: 745c0a53112e61d54bea5ea725f7fa92e3a2cdbb}
flutter: [Instance of 'InterceptorsWrapper']

Консоль при первом нажатии кнопки получения профиля

flutter: Http status error [403]
[VERBOSE-2:ui_dart_state.cc(177)] Unhandled Exception: DioError [DioErrorType.RESPONSE]: Http status error [403]
#0      DioMixin._request._errorInterceptorWrapper.<anonymous closure>.<anonymous closure>.<anonymous closure>
package:dio/src/dio.dart:870
#1      _rootRunUnary (dart:async/zone.dart:1198:47)
#2      _CustomZone.runUnary (dart:async/zone.dart:1100:19)
#3      _FutureListener.handleValue (dart:async/future_impl.dart:143:18)
#4      Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:696:45)
#5      Future._propagateToListeners (dart:async/future_impl.dart:725:32)
#6      Future._completeWithValue (dart:async/future_impl.dart:529:5)
#7      Future._asyncCompleteWithValue.<anonymous closure> (dart:async/future_impl.dart:567:7)
#8      _rootRun (dart:async/zone.dart:1190:13)
#9      _CustomZone.run (dart:async/zone.dart:1093:19)
#10     _CustomZone.runGuarded (dart:async/zone.dart:997:7)
#11     _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zon<…>

Консоль при последующем нажатии кнопки получения профиля

flutter: {id: 3, username: tester, first_name: , last_name: , email: [email protected]}

person Eli Per    schedule 21.01.2021    source источник
comment
не уверен, что это помогло? stackoverflow .com / questions / 56740793 /   -  person John Joe    schedule 21.01.2021
comment
@JohnJoe Спасибо, но это касается обновления просроченных токенов. Получаю свежие токены с логином.   -  person Eli Per    schedule 21.01.2021


Ответы (1)


Еще 5 часов и наконец разобрался с проблемой.

session.options.headers[HttpHeaders.authorizationHeader] = 'token ' + token;

должно быть

requestOptions.headers[HttpHeaders.authorizationHeader] = 'token ' + token;
person Eli Per    schedule 21.01.2021