Home > Mobile >  Understanding api calls and jwt token barrer
Understanding api calls and jwt token barrer

Time:08-04

I am new to Flutter and learning http.dart at present for api calls, I am using a .net web api with JWTToken Barrer with a /login end point.

Future<AuthenticationResponse> Authenticate() async {
  const loginEndpoint = "$baseURL/Login";

  http.Response response = await http.get(Uri.parse(loginEndpoint));

  if (response.statusCode == 200) {
    // If the server did return a 200 OK response,
    // then parse the JSON.

      JwtToken = field from response ?? add to headers
      return AuthenticationResponse.fromJson(jsonDecode(response.body));
    } else {
      // If the server did not return a 200 OK response,
      // then throw an exception.
     throw Exception('Failed to load players');
   }
}

My question is how do I get the jwt token from the json I am coming from c# this would be my model normally.

namespace Models
{
 public partial class AuthenicationResponseOjbect {
    public string Id { get; set; }
    public int PlayerId { get; set; }
    public Guid StoreId { get; set; }
    public Guid UserId { get; set; }
    public object FirstName { get; set; }
    public object LastName { get; set; }
    public string Username { get; set; }
    public string JwtToken { get; set; }  
    public object RefreshToken { get; set; }
   }
}

This is my dart model

import 'package:flutter/gestures.dart';

class AuthenticationResponse {
final int userId;
final String JwtToken;
final String FirstName;
final String LastName;

const AuthenticationResponse({
  required this.userId,
  required this.JwtToken,
  required this.FirstName,
  required this.LastName,
 });

 Map<String, dynamic> toJson() => {
    "userId": userId,
    "firstName": FirstName,
    "Lastname": LastName,
    "JwtToken": JwtToken
  };

 factory AuthenticationResponse.fromJson(Map<String, dynamic> json) {
  return AuthenticationResponse(
  userId: json['userId'],
  JwtToken: json['JwtToken'],
  FirstName: json['firstName'],
  LastName: json['LastName'],
  );
 }
 }

Also how would u load this via a button in a view ? Obviouslly I need to add the authentication token to the headers for this to work. I also need to send username and password to the /Login end point.

Thanks for advance help

CodePudding user response:

The steps for fetching the user tokens and putting them in each request is as follows:

1. Login to the login endpoint and parse the json body.

Note: You are using GET endpoint. This endpoint cannot handle a request body. Use a POST endpoint to send the username and password map for authentication. Otherwise, your current situation does not authenticate any credentials at all.

Future<AuthenticationResponse> Authenticate() async {
  const loginEndpoint = "$baseURL/Login";

  http.Response response = await http.get(Uri.parse(loginEndpoint));

  if (response.statusCode == 200) {
    // If the server did return a 200 OK response,
    // then parse the JSON.

      Map<String, dynamic> user = jsonDecode(response.body);

      return AuthenticationResponse.fromJson(user);
    } else {
      // If the server did not return a 200 OK response,
      // then throw an exception.
     throw Exception('Failed to load players');
   }
}

2. Save the user locally on secure storage or some other place


Future saveUserLocally()async {
    try {
        final user = await Authenticate();
        FlutterSecureStorage storage = FlutterSecureStorage();
        storage.write(key: 'current_user', value: jsonEncode(user.toJson()));

    } catch (e){
        // handle errors here or in your providers, I use repository to handle this


    }
}

3. Create a global header object that has all the headers for your case excluding the token

Map<String, dynamic> get headers => <String, dynamic>{
     'Content-Type':'application/json',
      'Accept': 'application/json',

}; 

4. Now, on your next request, fetch the local user and update header before making the request.


Future someRequest() async {

    // get local user
    FlutterSecureStorage storage = FlutterSecureStorage();
    final user = jsonDecode(await storage.read('current_user'));
   
    // Get global header
    var header = headers;
    
    // Add your token saved in user
    header['access_token'] = user['JwtToken']; // key from your namespace

    // Now, add the headers named header to http and make the call
    await http.get('url here', headers: header);

...
}

This is how you typically call the API.

Note: Not all of the exceptions are handled here. You will need to handle network errors and PlatformExceptions by yourself. Also, you must also check if the user exists or not in local storage, and handle 401 Unauthorized case as well. If 401 Unauthorized comes, you must gracefully signout the user.

  • Related