In this article, we will implement jwt auth with provider(app state)
Install prerequisites:
flutter pub add http
flutter pub add provider
flutter pub add flutter_secure_storage
flutter pub add shelf
flutter pub add shelf_router
flutter_secure_storage requires minSdk version >= 18
Implement a simple endpoint for getting a fake jwt token
We will use shelf_router to implement our authentication server. In an actual situation, you can use any way to implement it.
Implement fake jwt server:
lib/jwt_server.dart
import 'dart:convert';
import 'package:shelf_router/shelf_router.dart';
import 'package:shelf/shelf.dart';
import 'package:shelf/shelf_io.dart' as io;
void main() async {
var app = Router();
app.post('/login', (Request request) {
var json = jsonEncode({
'access_token': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c'
});
return Response.ok(json, headers: {
'Access-Control-Allow-Origin': '*'
});
});
await io.serve(app, 'localhost', 8080);
}
Now we have the server for testing our jwt auth
Implement authorizaion
Create auth model:
lib/models/auth.dart
import 'package:flutter/material.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
class AuthModel extends ChangeNotifier {
final storage = const FlutterSecureStorage();
String? _token;
bool isAuthorized = false;
init() async {
_token = await storage.read(key: 'token');
isAuthorized = _token != null;
notifyListeners();
}
login(String token) async {
storage.write(key: 'token', value: token);
_token = token;
isAuthorized = true;
notifyListeners();
}
logout() {
_token = null;
isAuthorized = false;
storage.delete(key: 'token');
notifyListeners();
}
}
Register auth model:
lib/main.dart
import 'package:flutter/material.dart';
import 'package:jwt_example/models/auth.dart';
import 'package:provider/provider.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
var authModel = AuthModel();
authModel.init();
return ChangeNotifierProvider(
create: (context) => authModel,
child: const MaterialApp(
home: MyHomePage(),
));
}
}
Implement view depends on auth:
lib/main.dart
...
import 'package:http/http.dart' as http;
import 'package:jwt_example/models/auth.dart';
...
class MyHomePage extends StatelessWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
// Listen auth model changes
var auth = context.watch<AuthModel>();
return OutlinedButton(
onPressed: () async {
if (auth.isAuthorized) {
auth.logout();
} else {
var url = Uri.parse('http://localhost:8080/login');
var response = await http.post(url);
var decodedResponse = jsonDecode(response.body) as Map;
auth.login(decodedResponse['access_token']);
}
},
child: auth.isAuthorized ? const Text("Logout") : const Text("Login"),
);
}
}
...
Run application:
dart run lib/jwt_server.dart
flutter run -d chrome
This simple example can be a point for extending to the specific realization of auth logic in your project.
Useful links:
Get and upgrade Dart
Creating app template
Simple app state management
JSON Web Token
Authentication with JWT in Dart(server)
Top comments (0)