diff --git a/lib/base/http/TraceDio.dart b/lib/base/http/TraceDio.dart index 56b68af..c397fb8 100644 --- a/lib/base/http/TraceDio.dart +++ b/lib/base/http/TraceDio.dart @@ -9,7 +9,10 @@ class TraceDio { final Uuid uuid = Uuid(); static late TraceDio _traceDio; + //token String? token; + //自定义查询条件 + Map queryParameters = {}; TraceDio(Logger? logger) : _dio = Dio(), @@ -25,6 +28,8 @@ class TraceDio { // 设置拦截器,自动添加 traceId 和 spanId,并记录日志 _dio.interceptors.add(InterceptorsWrapper( onRequest: (options, handler) { + //动态添加请求参数 + options.queryParameters.addAll(queryParameters); // 获取请求中的 traceId(如果没有则生成) String? traceId = options.headers['X-Trace-ID']; String? spanId = options.headers['X-Span-ID']; diff --git a/lib/base/redis/redis.dart b/lib/base/redis/redis.dart index af595e7..6c29040 100644 --- a/lib/base/redis/redis.dart +++ b/lib/base/redis/redis.dart @@ -62,6 +62,10 @@ class Redis { return await _command?.send_object(["GET", key]); } + Future delete(String key) async { + return await _command?.send_object(["DEL", key]) == "OK"; + } + Future setWithExpiry(String key, String value, int ttlInSeconds) async { var response = await _command ?.send_object(["SETEX", key, ttlInSeconds.toString(), value]); diff --git a/lib/base/webserver/WebServer.dart b/lib/base/webserver/WebServer.dart index 61507e2..baf317e 100644 --- a/lib/base/webserver/WebServer.dart +++ b/lib/base/webserver/WebServer.dart @@ -1,4 +1,3 @@ - abstract class WebServer { static late WebServer _webServer; @@ -10,7 +9,8 @@ abstract class WebServer { _webServer = server; } - void start(int port, {Function? interceptor}); + void start(int port, + {Function? interceptor, TokenResult Function(String?)? tokenCheck}); void stop(); void addHandler(handler); } @@ -58,9 +58,18 @@ class RequestMapping { final HttpMethod method; final String path; final HttpResponseType responseType; + final bool auth; const RequestMapping( {this.method = HttpMethod.ALL, required this.path, + this.auth = true, this.responseType = HttpResponseType.JSON}); } + +class TokenResult { + bool status; + String? errMsg; + Map? payload; + TokenResult({required this.status, this.errMsg, this.payload}); +} diff --git a/lib/base/webserver/impl/RouteGenerator.dart b/lib/base/webserver/impl/RouteGenerator.dart index a8c8f35..0818204 100644 --- a/lib/base/webserver/impl/RouteGenerator.dart +++ b/lib/base/webserver/impl/RouteGenerator.dart @@ -60,7 +60,8 @@ class RouteGenerator extends GeneratorForAnnotation { () { return method.name; }, - pl >= 2 ? 2 : 1 + pl >= 2 ? 2 : 1, + anno.read("auth").boolValue ]); } // print("构建完毕"); diff --git a/lib/base/webserver/impl/ShelfWebServer.dart b/lib/base/webserver/impl/ShelfWebServer.dart index b385be3..93bc5f5 100644 --- a/lib/base/webserver/impl/ShelfWebServer.dart +++ b/lib/base/webserver/impl/ShelfWebServer.dart @@ -1,3 +1,4 @@ +import 'dart:convert'; import 'dart:io'; import 'package:EasyDartModule/EasyDartModule.dart'; @@ -16,6 +17,7 @@ class ShelfWebServer implements WebServer { final Router _router = Router(); final Uuid uuid = Uuid(); final Map _wsCall = {}; + TokenResult Function(String?)? tokenCheck; ShelfWebServer(this.logger); final String tag = "webserver"; @@ -134,7 +136,9 @@ class ShelfWebServer implements WebServer { } @override - void start(int port, {Function? interceptor}) async { + void start(int port, + {Function? interceptor, + TokenResult Function(String?)? tokenCheck}) async { //反射获取全部路由地址 var pipeline = Pipeline() .addMiddleware(requestIdMiddleware()) @@ -151,6 +155,9 @@ class ShelfWebServer implements WebServer { }; }); } + if (tokenCheck != null) { + this.tokenCheck = tokenCheck; + } final handler = pipeline.addHandler(_routerHandler); _server = await serve(handler, InternetAddress.anyIPv4, port); print('Server listening on port ${_server?.port}'); @@ -161,6 +168,19 @@ class ShelfWebServer implements WebServer { _server?.close(); } + Response setResponseHeader(response, contentType) { + Map headers = {...response.headers}; + headers['Access-Control-Allow-Origin'] = '*'; + headers['Access-Control-Allow-Headers'] = + 'Content-Type,X-Span-ID,X-Trace-ID,token'; + headers["Access-Control-Expose-Headers"] = + "Content-Type,X-Span-ID,X-Trace-ID,token"; + headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE, OPTIONS'; + headers["content-type"] = contentType; + + return response.change(headers: headers); + } + @override void addHandler(handler) { try { @@ -179,33 +199,58 @@ class ShelfWebServer implements WebServer { } addRouter(k, p[0], (req, [a, b, c, d, e, f]) async { //从request中获取token并解码传入 - String? token = req.headers["token"]; + bool auth = true; + if (p.length >= 5) { + //判断是否需要进行token校验 + auth = p[4]; + } dynamic payload; - if (token != null) { - try { - payload = JWT.decode(token).payload; - } catch (e) { - //jwt解码失败 - print(e); + var response; + + if (auth) { + String? token = req.headers["token"]; + bool check = true; + if (tokenCheck != null) { + //自定义token校验函数存在 + var checkResult = tokenCheck!(token); + if (!checkResult.status) { + //校验失败 + response = Response.ok(checkResult.errMsg); + return setResponseHeader(response, p[1].type); + } + payload = checkResult.payload; + check = true; + } else { + if (token != null) { + try { + payload = JWT.decode(token).payload; + check = true; + } catch (e) { + //jwt解码失败 + print(e); + check = false; + } + } else { + check = false; + } + } + if (!check) { + response = + Response.ok(jsonEncode({"code": -10000, "msg": "token为空"})); + return setResponseHeader(response, p[1].type); } } - var response; + if (p[3] == 2) { response = await p[2](req, payload ?? {}); } else { response = await p[2](req); } - Map headers = {...response.headers}; - headers['Access-Control-Allow-Origin'] = '*'; - headers['Access-Control-Allow-Headers'] = - 'Content-Type,X-Span-ID,X-Trace-ID,token'; - headers["Access-Control-Expose-Headers"] = - "Content-Type,X-Span-ID,X-Trace-ID,token"; - headers['Access-Control-Allow-Methods'] = - 'GET, POST, PUT, DELETE, OPTIONS'; - headers["content-type"] = p[1].type; - - response = response.change(headers: headers); + if (response is! Response) { + //返回数据不是 Response 对象 + response = Response.ok(response.toString()); + } + response = setResponseHeader(response, p[1].type); return response; }); @@ -241,7 +286,8 @@ class ShelfWebServer implements WebServer { _router.options(path, (r) { return Response.ok('', headers: { 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Headers': 'Content-Type,X-Span-ID,X-Trace-ID,token', + 'Access-Control-Allow-Headers': + 'Content-Type,X-Span-ID,X-Trace-ID,token', 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', }); }); diff --git a/lib/base/webserver/impl/ShelfWebServer_none.dart b/lib/base/webserver/impl/ShelfWebServer_none.dart index 41b0168..b8d49e3 100644 --- a/lib/base/webserver/impl/ShelfWebServer_none.dart +++ b/lib/base/webserver/impl/ShelfWebServer_none.dart @@ -6,7 +6,8 @@ class ShelfWebServer implements WebServer { final String tag = "webserver"; ShelfWebServer(this.logger); @override - void start(int port, {Function? interceptor}) async {} + void start(int port, + {Function? interceptor, Function(String?)? tokenCheck}) async {} @override void stop() {}