В этой статье мы реализуем jwt auth с провайдером (app state).
Содержание
Установите предварительные условия:
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 требует minSdk версии >= 18
Реализуйте простую конечную точку для получения поддельного jwt-токена
Мы будем использовать shelf_router для реализации нашего сервера аутентификации. В реальной ситуации вы можете использовать любой способ его реализации.
Реализуйте поддельный jwt-сервер:
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);
}
Теперь у нас есть сервер для тестирования нашего jwt-аута.
Реализуйте авторизацию
Создайте модель авторизации:
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();
}
}
Зарегистрировать модель авторизации:
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(),
));
}
}
Реализовать представление в зависимости от 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"),
);
}
}
...
Запустить приложение:
dart run lib/jwt_server.dart
flutter run -d chrome
Этот простой пример может стать отправной точкой для расширения до конкретной реализации логики auth в вашем проекте.
Полезные ссылки:
Получение и обновление Dart
Создание шаблона приложения
Простое управление состоянием приложения
JSON Web Token
Аутентификация с помощью JWT в Dart (сервер)