authn.service.dart 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. import 'dart:io';
  2. import 'package:dio/dio.dart';
  3. import 'package:maxkey_flutter/persistent.dart';
  4. import 'package:maxkey_flutter/utils.dart';
  5. typedef ExpectedErrorHandler = void Function(String msg);
  6. class AuthnService {
  7. final Dio _dio;
  8. AuthnService(this._dio);
  9. /// 获取 state 类型
  10. Future<String?> get() async {
  11. try {
  12. LOGGER.i("AuthnService.get(): ");
  13. LOGGER.i("GET: /login/get?_allow_anonymous=true");
  14. final res = await _dio.get(
  15. "/login/get?_allow_anonymous=true",
  16. queryParameters: {"remember_me": true},
  17. );
  18. return res.data["data"]["state"];
  19. } catch (err) {
  20. LOGGER.e("AuthnService.get(): ");
  21. LOGGER.e(err);
  22. }
  23. return null;
  24. }
  25. /// 短信验证码
  26. Future<bool> produceOtp({
  27. required ExpectedErrorHandler expectedErrorHandler,
  28. required String mobile,
  29. }) async {
  30. try {
  31. LOGGER.i("AuthnService.produceOtp(): ");
  32. LOGGER.i("GET: /login/sendotp/$mobile?_allow_anonymous=true");
  33. final res = await _dio.get(
  34. "/login/sendotp/$mobile?_allow_anonymous=true",
  35. queryParameters: {"mobile": mobile},
  36. );
  37. if (res.data["code"] != 0) {
  38. final msg = res.data["message"] ?? "验证码发送失败";
  39. expectedErrorHandler(msg);
  40. LOGGER.w(msg);
  41. return false;
  42. }
  43. return true;
  44. } catch (err) {
  45. LOGGER.e("AuthnService.produceOtp(): ");
  46. LOGGER.e(err);
  47. }
  48. return false;
  49. }
  50. /// 账密登录
  51. Future<bool> loginNormal({
  52. required ExpectedErrorHandler expectedErrorHandler,
  53. required String state,
  54. required String username,
  55. required String password,
  56. required String captcha,
  57. }) async {
  58. try {
  59. LOGGER.i("AuthnService.loginNormal(): ");
  60. LOGGER.i("POST: /login/signin?_allow_anonymous=true");
  61. final res = await _dio.post(
  62. "/login/signin?_allow_anonymous=true",
  63. data: {
  64. "authType": "app",
  65. "state": state,
  66. "username": username,
  67. "password": password,
  68. "captcha": captcha,
  69. "remeberMe": true,
  70. },
  71. );
  72. if (res.data["code"] != 0) {
  73. final msg = res.data["message"] ?? "登陆失败";
  74. expectedErrorHandler(msg);
  75. LOGGER.w(msg);
  76. return false;
  77. }
  78. await onlineAuth(
  79. token: res.data["data"]["token"],
  80. onlineTicket: res.data["data"]["ticket"],
  81. username: res.data["data"]["username"],
  82. );
  83. return true;
  84. } catch (err) {
  85. LOGGER.e("AuthnService.loginNormal(): ");
  86. LOGGER.e(err);
  87. }
  88. return false;
  89. }
  90. Future<bool> scanCode({
  91. required ExpectedErrorHandler expectedErrorHandler,
  92. required String code,
  93. }) async {
  94. LOGGER.i("AuthnService.scanCode(): ");
  95. final token = MaxKeyPersistent.instance.token;
  96. if (token == null) {
  97. LOGGER.i("未登录");
  98. expectedErrorHandler("未登录");
  99. return false;
  100. }
  101. try {
  102. LOGGER.i("POST: /login/scanCode");
  103. final res = await _dio.post(
  104. "/login/scanCode",
  105. data: {"jwtToken": token, "code": code},
  106. );
  107. if (res.data["code"] != 0) {
  108. final msg = res.data["message"] ?? "扫码登陆失败";
  109. expectedErrorHandler(msg);
  110. LOGGER.w(msg);
  111. return false;
  112. }
  113. return true;
  114. } catch (err) {
  115. LOGGER.e("AuthnService.scanCode(): ");
  116. LOGGER.e(err);
  117. }
  118. return false;
  119. }
  120. Future<void> onlineAuth({
  121. required String token,
  122. required String onlineTicket,
  123. required String username,
  124. }) async {
  125. await MaxKeyPersistent.instance.setUser(username);
  126. await MaxKeyPersistent.instance.setToken(token);
  127. _dio.options.headers[HttpHeaders.authorizationHeader] = token;
  128. }
  129. bool localAuth() {
  130. final token = MaxKeyPersistent.instance.token;
  131. if (token == null) return false;
  132. _dio.options.headers[HttpHeaders.authorizationHeader] = token;
  133. return true;
  134. }
  135. /// 登出并清除本地缓存的 token
  136. Future<void> logout() async {
  137. try {
  138. LOGGER.i("AuthnService.logout(): ");
  139. LOGGER.i("GET: /logout");
  140. await _dio.get("/logout").timeout(const Duration(seconds: 5));
  141. } catch (err) {
  142. LOGGER.e("AuthnService.logout(): ");
  143. LOGGER.e(err);
  144. }
  145. _dio.options.headers.remove(HttpHeaders.authorizationHeader);
  146. await MaxKeyPersistent.instance.clearToken();
  147. }
  148. }