Flutter http Post-StatusCode 401-重复响应

时间:2019-06-15 09:12:44

标签: php http flutter

在Flutter中,我的Http Post Request遇到了一些麻烦。我必须连接到PHP Web服务(使用标头),并发布一些用户/密码信息以获得响应(此处为用户信息)。 我相信我已经接近解决方案,但是尽管在尝试使用Postman(具有相同凭据)时它仍然有效,但仍然得到StatusCode 401作为响应。

这是我调用的函数的代码:

Future<http.Response> post() async {

  var url = "https://www.monadresse/login.php";
  String password = "xxx";
  String username = "yyy";
  //var bytes = utf8.encode("$username:$password");
  var bytes = "$username:$password";
  String userNameUser = "www";
  String passwordUser = "zzz";
  var passwordUserEncoded = base64.encode(utf8.encode(passwordUser));
//var passwordUserEncoded = base64.encode(passwordUser);
  var headers = {
    "Authorization": "Basic $bytes",
    "Content-Type": "application/json",
  };
  var requestBody = json.encode({ 'user': userNameUser, 'password': passwordUserEncoded});
  print(headers);
  print(requestBody);

  final http.Response response = await http.post(
    url,
    body: requestBody,
    headers: headers,
  );
  if(response.statusCode == 200){
    var responseJson = json.decode(response.body);
    print(Utf8Codec().decode(response.bodyBytes));

    print("Body: " + responseJson);}

  print(bytes);
  print(passwordUserEncoded);
  print(response.statusCode);
  print("Fini");
}

另外一件奇怪的事情(读为“我不明白”)...我添加了一些打印件,以了解发生的情况,如下所示,前两个打印件(位于请求之前)是首先打印两次,然后最后3次打印也重复两次。

flutter: {Authorization: Basic yyy:xxx, Content-Type: application/json}
flutter: {"user":"www","password":"zzz"}
flutter: {Authorization: yyy:xxx, Content-Type: application/json}
flutter: {"user":"www","password":"zzz}
flutter: yyy:xxx
flutter: zzz
flutter: 401
flutter: Fini
flutter: yyy:xxx
flutter: zzz
flutter: 401
flutter: Fini

由于我在网上找不到解决方案,所以我非常希望有人能帮助我。

1 个答案:

答案 0 :(得分:0)

如评论中所述,此问题的原因是授权标头中使用的'username:password'未编码为base64。

以下是使用test endpoints from Postman进行基本身份验证的工作示例。用户名是postman,密码是password

import 'dart:io';

import 'package:flutter/material.dart';

import 'package:http/http.dart' as http;
import 'dart:convert' show utf8, base64;

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  var _usernameTextController = TextEditingController();
  var _passwordTextController = TextEditingController();
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Container(
          padding: EdgeInsets.all(16.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              TextFormField(
                controller: _usernameTextController,
                decoration: const InputDecoration(
                  labelText: 'Username',
                ),
              ),
              TextFormField(
                controller: _passwordTextController,
                obscureText: true,
                decoration: const InputDecoration(
                  labelText: 'Password',
                ),
              ),
              ElevatedButton(
                child: Text('Login'),
                onPressed: _doLogin(_usernameTextController.text, _passwordTextController.text),
              )
            ],
          ),
        ),
      ), 
    );
  }

  _doLogin(String username, String password) {
    if (username.trim().isEmpty || password.trim().isEmpty) {
      debugPrint('Either username or password is empty');
    } else {
      _login(username, password)
          .then((value) => debugPrint('Login finished $value'))
          .catchError((error) => debugPrint('Login error: $error'));
    }
  }

  Future _login(String username, String password) async {
    // 'username:password' is base64 encoded
    var authHeader = '${base64.encode(utf8.encode('$username:$password'))}';
    debugPrint('userpass: ${username + password}');
    debugPrint('authHeader: $authHeader');
    final response = await http.get(
      'https://postman-echo.com/basic-auth',
      headers: {HttpHeaders.authorizationHeader: "Basic $authHeader"},
    );
    if (response.statusCode == 200) {
      // If the server did return a 200 OK response,
      // then parse the JSON.
      return response.body;
    } else {
      // If the server did not return a 200 OK response,
      // then throw an exception.
      throw Exception(
          'Failed to login [${response.statusCode}] ${response.body}');
    }
  }
}