Mark Kipchumba
Mark Kipchumba

Reputation: 11

Login fails due to Connection or Authentication Issues in Flutter App using Access Tokens

I am trying to login and fetch the user details. When I insert the mapVendorNumber and username strings, the code will combine the two as a final username (formattedUsername), then I am using a token url where the username and password will be sent and verified and if correct and existing, then it will fetch the access-token generated. The access token will now be the Authorization (Basic access-token) in the fetch user detail url, but I am having an issue retrieving. It gives me this error every time:

CompilationError: The getter 'response' isn't defined for the class '_LoginPageState'.

'_LoginPageState' is from 'package:frontend/pages/login_page.dart' ('lib/pages/login_page.dart').

Try correcting the name to the name of an existing getter, or defining a getter or field named 'response'.response^^^^^^^^

This part of the code below is used to retrieve the access token after proper checking of the details submitted it should then generate the token and allow redirection to fetching the user details:

class _LoginPageState extends State<LoginPage> {
  final _formKey = GlobalKey<FormState>();

  final TextEditingController _mapVendorNumberController = TextEditingController();
  final TextEditingController _usernameController = TextEditingController();
  final TextEditingController _passwordController = TextEditingController();

  final String tokenUrl = "https:hidden";
  final String userDetailsUrl = "https:hidden";
  final String authorizationHeader =
      "Basic hidden";

  @override
  void initState() {`your text`
    super.initState();`your text`
    _checkLoginStatus();
  }

  Future<void> _checkLoginStatus() async {
    final prefs = await SharedPreferences.getInstance();
    String? token = prefs.getString('access_token');

    if (token != null) {
      await _fetchUserDetails(token);
    }
  }

  Future<void> _login() async {
    if (!_formKey.currentState!.validate()) return;

    String mapVendorNumber = _mapVendorNumberController.text.trim();
    String username = _usernameController.text.trim();
    String password = _passwordController.text.trim();
    String formattedUsername = "$mapVendorNumber#$username";

    try {
      var tokenResponse = await http.post(
        Uri.parse(tokenUrl),
        headers: {
          'Authorization': authorizationHeader,
          'Content-Type': 'application/x-www-form-urlencoded',
        },
        body: {
          'username': formattedUsername,
          'password': password,
          'grant_type': 'password',
        },
      );

      if (tokenResponse.statusCode == 200) {
        var tokenData = json.decode(tokenResponse.body);
        String accessToken = tokenData['access_token'];

        final prefs = await SharedPreferences.getInstance();
        await prefs.setString('access_token', accessToken);

        await _fetchUserDetails(accessToken);
      } else {
        _showError("Invalid credentials. Please try again.");
      }
    } catch (e) {
      _showError("An error occurred. Please check your connection.");
    }
  }

This part of the code then takes the access token to be used as the authorization header and then fetch the user details:

Future<void> _fetchUserDetails(String token) async {
    try {
      var response = await http.get(
        Uri.parse(userDetailsUrl),
        headers: {
          'Authorization': 'Bearer $token',
          'Content-Type': 'application/json',
        },
      );

      if (response.statusCode == 200) {
        var userDetails = json.decode(response.body);
        Navigator.pushReplacement(
          context,
          MaterialPageRoute(
              builder: (context) => CustomerPage(userDetails: userDetails)),
        );
      } else {
        _showError("Failed to fetch user details.");
      }
    } catch (e) {
      _showError("An error occurred while fetching user details.");
    }
  }

I tried to change the response type from "response" to "token response" but still it didn't resolve my problem.
On proper detail insertion, it will fetch the token, then the token will be used as the authorization header, then the details of the user should be fetched.

Upvotes: 1

Views: 25

Answers (0)

Related Questions