fix:商城登录互通问题
This commit is contained in:
1 parent
7b1852d9a6
commit
1f9a8b67a2
4 files changed
+119
-9
No files matched your search
@@ -47,11 +47,19 @@ class LoginPage extends HookConsumerWidget {
|
|||||||
Future<void> returnAfterLogin() async {
|
Future<void> returnAfterLogin() async {
|
||||||
final target = next?.trim();
|
final target = next?.trim();
|
||||||
final router = GoRouter.of(context);
|
final router = GoRouter.of(context);
|
||||||
if (target == null || target.isEmpty) {
|
if (target != null && target.isNotEmpty) {
|
||||||
router.go(AppRoutes.profile);
|
router.go(target);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
router.go(target);
|
// The mall opens this page with no `next`. Pop back to its resident
|
||||||
|
// WebView so the auth-state listener can deliver `enterWebMall` after
|
||||||
|
// the app-mall token has been issued. Replacing the route here disposes
|
||||||
|
// that WebView before the asynchronous hand-off can finish.
|
||||||
|
if (context.canPop()) {
|
||||||
|
context.pop();
|
||||||
|
} else {
|
||||||
|
router.go(AppRoutes.profile);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void startCountdown() {
|
void startCountdown() {
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
|
||||||
@@ -25,17 +27,25 @@ class MallAuthApi {
|
|||||||
Future<AppMallAuthToken> issueAppMallAuthToken() async {
|
Future<AppMallAuthToken> issueAppMallAuthToken() async {
|
||||||
final response = await _dio.post<List<int>>(
|
final response = await _dio.post<List<int>>(
|
||||||
'/api/v1/auth/mall/app-token',
|
'/api/v1/auth/mall/app-token',
|
||||||
data: const <int>[],
|
// Dio serializes a List<int> as the UTF-8 text "[]". This endpoint
|
||||||
|
// expects an empty protobuf message, whose wire representation is zero
|
||||||
|
// bytes; Uint8List keeps the request body binary and untransformed.
|
||||||
|
data: Uint8List(0),
|
||||||
options: protobufOptions(),
|
options: protobufOptions(),
|
||||||
);
|
);
|
||||||
final reply = ProtoMessage(response.data ?? const <int>[]);
|
final reply = ProtoMessage(response.data ?? const <int>[]);
|
||||||
final token = reply.string(1).trim();
|
final token = reply.string(1).trim();
|
||||||
if (token.isEmpty) throw const FormatException('Missing mall auth token');
|
final expiresIn = reply.integer(2);
|
||||||
|
final sourceApp = reply.string(3).trim();
|
||||||
|
final scene = reply.string(4).trim();
|
||||||
|
if (token.isEmpty || expiresIn <= 0 || sourceApp.isEmpty || scene.isEmpty) {
|
||||||
|
throw const FormatException('Incomplete mall auth token response');
|
||||||
|
}
|
||||||
return AppMallAuthToken(
|
return AppMallAuthToken(
|
||||||
authToken: token,
|
authToken: token,
|
||||||
expiresIn: reply.integer(2),
|
expiresIn: expiresIn,
|
||||||
sourceApp: reply.string(3),
|
sourceApp: sourceApp,
|
||||||
scene: reply.string(4),
|
scene: scene,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@ name: jinzhi_flutter_app
|
|||||||
description: "金值 - 贵金属资产管家"
|
description: "金值 - 贵金属资产管家"
|
||||||
publish_to: 'none'
|
publish_to: 'none'
|
||||||
|
|
||||||
version: 1.0.0+1
|
version: 1.3.0+1
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ^3.9.2
|
sdk: ^3.9.2
|
||||||
|
|||||||
@@ -0,0 +1,92 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:dio/dio.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:jinzhi_flutter_app/features/mall/data/mall_auth_api.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
test('sends an empty protobuf body when issuing a mall auth token', () async {
|
||||||
|
Object? requestData;
|
||||||
|
String? contentType;
|
||||||
|
final dio = Dio()
|
||||||
|
..interceptors.add(
|
||||||
|
InterceptorsWrapper(
|
||||||
|
onRequest: (options, handler) {
|
||||||
|
requestData = options.data;
|
||||||
|
contentType = options.contentType;
|
||||||
|
handler.resolve(
|
||||||
|
Response<List<int>>(
|
||||||
|
requestOptions: options,
|
||||||
|
statusCode: 200,
|
||||||
|
data: _validResponse(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
final token = await MallAuthApi(dio).issueAppMallAuthToken();
|
||||||
|
|
||||||
|
expect(requestData, isA<Uint8List>());
|
||||||
|
expect(requestData, isEmpty);
|
||||||
|
expect(contentType, 'application/x-protobuf');
|
||||||
|
expect(token.authToken, 'mall-token');
|
||||||
|
expect(token.expiresIn, 300);
|
||||||
|
expect(token.sourceApp, 'jinzhi');
|
||||||
|
expect(token.scene, 'web_mall');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('rejects an incomplete mall auth token response', () async {
|
||||||
|
final dio = Dio()
|
||||||
|
..interceptors.add(
|
||||||
|
InterceptorsWrapper(
|
||||||
|
onRequest: (options, handler) {
|
||||||
|
handler.resolve(
|
||||||
|
Response<List<int>>(
|
||||||
|
requestOptions: options,
|
||||||
|
statusCode: 200,
|
||||||
|
data: _stringField(1, 'mall-token'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
await expectLater(
|
||||||
|
MallAuthApi(dio).issueAppMallAuthToken(),
|
||||||
|
throwsFormatException,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
List<int> _validResponse() => <int>[
|
||||||
|
..._stringField(1, 'mall-token'),
|
||||||
|
..._integerField(2, 300),
|
||||||
|
..._stringField(3, 'jinzhi'),
|
||||||
|
..._stringField(4, 'web_mall'),
|
||||||
|
];
|
||||||
|
|
||||||
|
List<int> _stringField(int field, String value) {
|
||||||
|
final bytes = utf8.encode(value);
|
||||||
|
return <int>[
|
||||||
|
..._varint((field << 3) | 2),
|
||||||
|
..._varint(bytes.length),
|
||||||
|
...bytes,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
List<int> _integerField(int field, int value) => <int>[
|
||||||
|
..._varint(field << 3),
|
||||||
|
..._varint(value),
|
||||||
|
];
|
||||||
|
|
||||||
|
List<int> _varint(int value) {
|
||||||
|
final bytes = <int>[];
|
||||||
|
while (value > 0x7f) {
|
||||||
|
bytes.add((value & 0x7f) | 0x80);
|
||||||
|
value >>= 7;
|
||||||
|
}
|
||||||
|
bytes.add(value);
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
Reference in new issue
Block a user