Skip to content

Instantly share code, notes, and snippets.

@zamahaka
Created June 29, 2021 10:19
Show Gist options
  • Save zamahaka/5bcee99dd9d58924fce4254f4d4df7a5 to your computer and use it in GitHub Desktop.
Save zamahaka/5bcee99dd9d58924fce4254f4d4df7a5 to your computer and use it in GitHub Desktop.
auth
import 'dart:convert';
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import 'package:mymilkman/general/utils/dio_utils.dart';
import 'package:mymilkman/repository/local/token_store.dart';
import 'package:pretty_dio_logger/pretty_dio_logger.dart';
const BaseUrl = 'https://staging.api.mymilkman.ie/Api/';
const ConnectTimeout = 15000;
Map<String, String> authHeader(String token) =>
{'Authorization': 'Basic $token'};
Options authOptions(String token) => Options(headers: authHeader(token));
String createToken({String passwordHash, String email}) =>
base64.encode(utf8.encode('$email:$passwordHash'));
Dio createDio() {
Dio dio = Dio();
dio.options.baseUrl = BaseUrl;
dio.options.connectTimeout = ConnectTimeout;
if (kDebugMode) _installLogger(dio);
return dio;
}
Dio createAuthenticatedDio(TokenStore store, {VoidCallback onUnauthenticated}) {
Dio dio = Dio();
dio.options.baseUrl = BaseUrl;
dio.options.connectTimeout = ConnectTimeout;
_installAuthentication(dio, store, onUnauthenticated: onUnauthenticated);
if (kDebugMode) _installLogger(dio);
return dio;
}
void _installLogger(Dio dio) {
dio.interceptors.add(PrettyDioLogger(
requestHeader: true,
requestBody: true,
responseBody: true,
responseHeader: false,
error: true,
compact: true,
maxWidth: 90,
));
}
void _installAuthentication(
Dio dio,
TokenStore store, {
VoidCallback onUnauthenticated,
}) {
dio.interceptors.add(HttpAuthInterceptor(
store: store,
onUnauthenticated: onUnauthenticated,
));
}
class HttpAuthInterceptor extends Interceptor {
final TokenStore store;
final VoidCallback onUnauthenticated;
HttpAuthInterceptor({
@required this.store,
this.onUnauthenticated,
}) : assert(store != null);
Future onRequest(RequestOptions options) async {
final token = await store.getToken();
return options.merge(headers: authOptions(token).headers);
}
@override
Future onError(DioError error) async {
final code = maybeResponseCode(error);
if (code == 401) onUnauthenticated?.call();
return error;
}
}
import 'package:flutter/foundation.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
class MissingTokenException implements Exception {}
class TokenStore {
static const String TOKEN = 'token';
final FlutterSecureStorage storage;
const TokenStore({@required this.storage}) : assert(storage != null);
Future<bool> hasToken() =>
storage.read(key: TOKEN).then((token) => token != null);
Future<String> getToken() => storage.read(key: TOKEN).then((token) {
if (token == null) throw MissingTokenException();
return token;
});
Future<void> persistToken(String token) =>
storage.write(key: TOKEN, value: token);
Future<void> deleteToken() => storage.delete(key: TOKEN);
Future<void> clear() => deleteToken();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment