DEV Community

Cover image for User Authentication + JWT Authorization With Flutter and Node

User Authentication + JWT Authorization With Flutter and Node

Carmine Zaccagnino on February 18, 2020

Cover Photo by James Sutton on Unsplash The series of posts about advanced networking topics applied to Flutter apps continues. As always, this is...
Collapse
 
bisquits profile image
Melinda Uivari • Edited

I have a question: how do I use the user data in the payload on other pages of my app (other than the homepage)? Do I pass the payload for each class? Thanks a lot in advance! EDIT: I have seen that the solution could be a singleton object. What other ways can be?

Collapse
 
carminezacc profile image
Carmine Zaccagnino

The general approach to shared data across pages in Flutter is to use an InheritedWidget or simpler alternatives to it like the provider package. I hope this answered your question.

Collapse
 
asiamov profile image
asiamov

On that note: how would you go about using the token itself for every api call in other parts of the app? Right now I’m getting the JWT out of secure storage for every api call I make but I wonder if that’s efficient.

Thread Thread
 
carminezacc profile image
Carmine Zaccagnino • Edited

You can fetch once when the app starts and then have an InheritedWidget or Provider above all of your widgets provide the JWT without having to fetch it from local storage every time.

Thread Thread
 
asiamov profile image
asiamov

Right, thought about doing that as well. Wasn’t sure because of security but I guess in memory (ie provider) is alright while secure storage at rest.

Collapse
 
bisquits profile image
Melinda Uivari • Edited

Thanks a lot! I was looking for this.
Also a tip: if you're using non-ascii characters in the username or other user data that you store in the payload, you will get a format exception. (I needed some time to figure out what had caused the problem, hahah!) The fix is to use utf8.decode() instead of ascii.decode().

Collapse
 
carminezacc profile image
Carmine Zaccagnino

You're completely right! I'm sorry I didn't read your comments earlier but I was really busy and didn't notice!

Collapse
 
ycv005 profile image
Yash Chandra Verma • Edited

You didn't mention it, by the way thanks for the article
(See the Readme of plugin)
Note By default Android backups data on Google Drive. It can cause exception java.security.InvalidKeyException:Failed to unwrap key. You need to

disable autobackup, details
exclude sharedprefs FlutterSecureStorage used by the plugin, details

Collapse
 
anfimovoleh profile image
Oleh Anfimov

Awesome article! Thank you so much

Collapse
 
ivanyoed profile image
Iván Gonzaléz • Edited

Thanks a lot for this article and also for the advanced flutter networking series. The way you write is very understandable. I also like that, when you use a simplified example, you do mention that in order to not let the reader fall into bad habits. Looking forward to finishing the whole series and also reading more articles from you. Greetings from Mexico.

Collapse
 
chonghorizons profile image
chonghorizons

We are trying to write some code to help with coronavirus response internationally. Thanks for this clear explanation of JWT with Flutter and NodeJS. I appreciate the clean and simple github code.

We're working on an app for coronavirus volunteer coordination. This is the premise: tinyurl.com/Boots3CaretakersUserStory and tinyurl.com/Boots3Caretakers

I could use some code review. We could pay you or you could volunteer your time. (We're all volunteers)

I'm hocho on discord. Those docs give directions on how to find me.

Collapse
 
damianoux profile image
Damianoux

Hi Carmine, Good tutorial.
I followed it, but I got problem in HomePage class, in the FutureBuilder.
I was not able to get it working in the original form, I had to modify the headers as follows (my data GET route is /api/auth/profile):

          future: http.read('$SERVER_IP/api/auth/profile', headers: {
            "Authorization": json.decode(jwt)["token_type"] +
                " " +
                json.decode(jwt)["access_token"]
          }),
Enter fullscreen mode Exit fullscreen mode

Using "Authorization": jwt, passed in the whole json and the server did not authenticate, so I was redirect to login ang got error 405 (because /api/auth/login requires POST).

On the server I have nginx+ Laravel 8 and followed the recomended instruction to install jwt-auth.

DId I miss somenthing in the cofiguration of the server?

Thx
Damiano

Collapse
 
abrahamkeleta profile image
Abraham Keleta

Thank you for this great tutorial. This was super helpful!

Collapse
 
pasonmoasca profile image
pasonmoasca

Ciao, avrei una domanda: con flutter effettuo il login con un json ma non funziona, nel senso che anche se metti le credenziali sbagliate da 200 (cioè ok). Ho solo inserito un file json (login.json). il server in cui risiede il json è un HOSTING L.A.M.P. (Linux / Apache / MySQL / PHP), devi creare qualcosa di speciale o sbaglio la struttura del json? Penso che lato Flutter sia tutto ok....

File Json
{
"email": "eve.holt@reqres.in",
"password": "cityslicka"
}

api_service.dart
import 'package:http/http.dart' as http;
import 'dart:convert';
import '../model/login_model.dart';

class APIService {
Future login(LoginRequestModel requestModel) async {
String url = "nextesa.it/api/login";

final response = await http.post(url, body: requestModel.toJson());
if (response.statusCode == 200 || response.statusCode == 400) {
  return LoginResponseModel.fromJson(
    json.decode(response.body),
  );
} else {
  throw Exception('Failed to load data!');
}
Enter fullscreen mode Exit fullscreen mode

}
}

Collapse
 
carminezacc profile image
Carmine Zaccagnino

Chiedo scusa se rispondo tardi, ma non accedevo a DEV da tanto. In ogni caso, da questi snippet non vedo niente di anomalo, consiglio di mandarmi una mail a carmine@carminezacc.com in questi casi.

Collapse
 
toby14 profile image
Toby14

Thanks for sharing this. I have a question, for this implementation, does your app get the user logged in after the app completely closed or the jwt get lost after that? I am wondering if the flutter_secure_storage package is the best choice to use if I want to save the jwt so that when I reopen the app I don't have to log in. Thanks in advance!

Collapse
 
juehuayou profile image
JuehuaYou

hi Carmine Zaccagnino, thank for your sharing. It is very helpful!

I have a question about JWT and TokenAuthentication. What is the difference between them ? Do they perform the same for flutter mobile app connect to API?

Collapse
 
carminezacc profile image
Carmine Zaccagnino

What do you mean by TokenAuthentication? Token-based authentication is always the same as far as the frontend/mobile app is concerned, the difference is in how the backend generates the access token: it can be generated with sessions as random strings that are both stored in a database and sent to the frontend so that the backend can compare to the values it has in the database, it can be generated as an encrypted payload or, in the case of JWTs, as a signed payload encoded in base64.

Collapse
 
nahuelcabrera profile image
Nahuel Cabrera

Thanks for your work!
Awesome post, regards

Collapse
 
stemper0123 profile image
Patryk Stemporowski

It's an amazing tutorial, but consider not putting the text in the code field next time because the text is not breaking. I don't exactly know what you can actually control on this website (probably not that much), but these five lines in the pre tag fix it: white-space: pre-wrap; /* Since CSS 2.1 / white-space: -moz-pre-wrap; / Mozilla, since 1999 / white-space: -pre-wrap; / Opera 4-6 / white-space: -o-pre-wrap; / Opera 7 */ word-wrap: break-word;

Collapse
 
m8811163008 profile image
m8811163008

Thank you
when use express.urlencoded() ?

Collapse
 
lucasglmt profile image
Lucas

Thank you so much !

Collapse
 
med_dernoun profile image
Mohamed Dernoun

Great tutorial, is there a way on how to refresh the token without using username and password ?

Collapse
 
goriet profile image
Goriet.d

Hi, how i can do this but with a image plisssss <3 and thanks

Collapse
 
carminezacc profile image
Carmine Zaccagnino

You'd have to store the image somewhere else and then exchange JSON objects with your backend instead of directly sending the message so you can specify whether you're sending an image or something else.

Collapse
 
paikman7 profile image
paikman7

How would I implement this using the mongoDB database instead?

Collapse
 
carminezacc profile image
Carmine Zaccagnino

You would need to change the backend to use the MongoDB driver instead of the SQLite one, connect to your MongoDB database instead of using SQLite database files and then store the documents using the MongoDB driver API.

Since MongoDB is a NoSQL document storage database, the changes you'd have to make to the code are significant.

Collapse
 
paikman7 profile image
paikman7

Also, would this be a similar structure to creating a email/password authentication system?

Collapse
 
carminezacc profile image
Carmine Zaccagnino

It's pretty much the same thing, email authentication usually involves validating the email address, sending confirmation emails and allowing for password reset. Without those features it's exactly the same thing, you can just use an email as the username.