Как сделать пользовательский заголовок в http-запросе флаттера - PullRequest
0 голосов
/ 12 февраля 2020

Я хочу сделать простой почтовый запрос, но что-то не работает.

В front-end angular заголовки http сделаны так:

let header = {
      headers: new HttpHeaders({
        "Content-Type": "application/json",
        user: JSON.stringify(JSON.parse(localStorage.getItem("user")).values)
      })
    };

в app Flutter Я пытался сделать что-то подобное, но все, что я делаю, возвращает ошибку 500, потому что заголовки не верны

технически мне нужно сделать так

final Map< String, String> headers = {
      "Content-Type" : "application/json",
      "user" : { 
                 "token": "BLABLABLA",
                 "user_id" : "1"
               } 
} ;

Это должно работать так же, как и внешний интерфейс angular, потому что серверная часть была сделана так:

вход выполнен и работает, мы сохраняем информацию для входа с помощью SharedPreferences

1 Ответ

1 голос
/ 13 февраля 2020

Это хороший вопрос. Многие люди используют библиотеки-оболочки для базовой библиотеки http, но, похоже, вы используете только базовую библиотеку. Я думаю, что проблема в том, что вы создаете заголовок, как если бы он был Map<String, dynamic>, когда он действительно должен быть Map<String, String>.

В зависимости от настроек вашего сервера, вы, вероятно, могли бы заставить это работать так:

final Map< String, String> headers = {
  "Content-Type" : "application/json",
  "user" : jsonEncode({ // add this function call around your object
             "token": "BLABLABLA",
             "user_id" : "1"
           }),
};

Использование этого выше создаст два заголовка:

Content-Type: application/json
user: {"token":"BLABLABLA","user_id":1}

Однако вы можете этого не захотеть, потому что некоторые серверы не любят символы {} или "" в содержание заголовка. Вместо этого вы можете сделать еще два варианта:

= метод Base 64 =

попытаться выполнить base64 эту json строку в вашем заголовке, а затем на стороне сервера base64 закодировать ее :

final Map< String, String> headers = {
  "Content-Type" : "application/json",
  "user" : stringToBase64.encode( // additionally base64 encode it
             jsonEncode({ // add this function call around your object
               "token": "BLABLABLA",
               "user_id" : "1"
             }),
           ),
};

= метод URL Encode =

urlencode, заголовок которого должен работать для большинства серверов:

final Map< String, String> headers = {
  "Content-Type" : "application/json",
  "user" : Uri.encodeQueryComponent( // additionally base64 encode it
             jsonEncode({ // add this function call around your object
               "token": "BLABLABLA",
               "user_id" : "1"
             }),
           ),
};

= Предложение =

Если вы просто пытаетесь использовать базовый c JWT, вы можете просто пропустить весь этот пользовательский параметр и вставить свой токен в стандартный формат Authorization: Bearer TOKEN. Вот рабочий пример, который я извлек и изменил из одного из моих проектов, который делает именно это:

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

String _getToken() {
  return 'MY_BEARER_TOKEN';
}

class BaseNetworking {
  Future<http.Response> post(
    String url,
    Map<String, dynamic> data, {
    Map<String, String> headers,
  }) async {
    final Uri uri = Uri.parse(url);

    return await http.post(
      uri,
      headers: _buildHeaders(
        requiresAuth: true,
        extra: headers,
      ),
      body: jsonEncode(data),
    );
  }

  /// build the headers for the given request. might include authorization or any number of other headers
  Map<String, String> _buildHeaders({
    bool requiresAuth = true,
    Map<String, String> extra,
  }) {
    final Map<String, String> headers = <String, String>{
      'Accept': 'application/json; charset=utf-8',
      'User-Agent': 'AppName (version: 1.0.0)',
    };

    if (extra is Map<String, String>) {
      headers.addAll(extra);
    }

    if (requiresAuth) {
      headers['Authorization'] = 'Bearer ${_getToken()}';
    }

    return headers;
  }
}
...