Тип аргумента «Set» не может быть присвоен типу параметра » Map»

#flutter #jwt #auth0 #flutter-http

Вопрос:

Я пытаюсь создать систему аутентификации пользователей с помощью Auth0 в своем приложении Flutter. В документации Auth0 REST приведен пример cURL, но я не нашел никакого пакета flutter, который выполняет работу cURL. Итак, я использовал http . Вот код:

   Future<String> getToken(String userId) async {
    final response = await http.post(
      Uri.parse('https://my-auth0-subdomain.auth0.com/oauth/token'),  // I used my real subdomain
      body: jsonEncode({
        'grant_type=client_credentials',
        'client_id=my_project_client_id',  // I used my real client id
        'client_secret=my_project_client_secret',  // I used my real client secret
        'audience=https://my-auth0-subdomain.auth0.com/api/v2/'  // I used my real subdomain
      }),
      headers: {
        'content-type: application/x-www-form-urlencoded'
      },
    );
    final token = jsonDecode(response.body)["access_token"];

    return token;
  }
 

Это дает мне ошибку, которая The argument type 'Set<String>' can't be assigned to the parameter type 'Map<String, String>'. в строке 10 ( headers: {...} ).
Я могу устранить эту ошибку с помощью headers: {'content-type': 'application/x-www-form-urlencoded'}, .
Но затем это приводит к ошибке от Auth0 {"error":"access_denied","error_description":"Unauthorized"} . API настроен правильно, потому что при запуске

 curl --request POST 
  --url 'https://my-auth0-subdomain.auth0.com/oauth/token' 
  --header "content-type: application/x-www-form-urlencoded" 
  --data grant_type=client_credentials 
  --data 'client_id=my_project_client_id' 
  --data client_secret=my_project_client_secret 
  --data 'audience=https://my-auth0-subdomain.auth0.com/api/v2/'
 

он возвращает a "access_token" , "scope" , "expires_in" и "token_type" .

Пожалуйста, помогите. Это очень важно.
Заранее спасибо 🙂

Комментарии:

1. Вместо 'grant_type=client_credentials' использования 'grant_type':'client_credentials' . Каждое значение, которое вы должны изменить, вот так

2. @MidhunMP Но если я это сделаю, то ответ будет {"error":"access_denied","error_description":"Unauthorized"} таким . Я думаю, что Auth0 принимает только "content-type: application/x-www-form-urlencoded" и не "content-type": "application/x-www-form-urlencoded" .

3. Почему вы отправляете тело как код jsonEncode и устанавливаете тип содержимого заголовка как приложение/x-www-форма-url-код, а не приложение/json

4. @MidhunMP Спасибо за предложение! Я смешал ваше предложение со своим кодом, и оно сработало! Не знаю как 😅 но это работает

5. @Dev Auth0 сказал, что он строго хочет, чтобы URL-адрес приложения/x-www-формы был закодирован и что он не примет никакого другого типа заголовка

Ответ №1:

Попробуйте отправить данные в виде URL, закодированного с помощью :

 Map<String, String> myBody= {

'grant_type' : 'client_credentials',
        'client_id' : 'my_project_client_id',  // I used my real client id
        'client_secret' : 'my_project_client_secret',  // I used my real client secret
        'audience ' : 'https://my-auth0-subdomain.auth0.com/api/v2/'  // I used my real subdomain     
};

Future<String> getToken(String userId) async {
    final response = await http.post(
      Uri.parse('https://my-auth0-subdomain.auth0.com/oauth/token'),  // I used my real subdomain
      body: myBody,
      headers: {
        'content-type: application/x-www-form-urlencoded'
      },
    );
    final token = jsonDecode(response.body)["access_token"];

    return token;
  }