更新web服务器自定义token解析回调

This commit is contained in:
2025-04-18 11:06:34 +08:00
parent 700479d131
commit cff5448fe0
6 changed files with 91 additions and 25 deletions

View File

@@ -9,7 +9,10 @@ class TraceDio {
final Uuid uuid = Uuid(); final Uuid uuid = Uuid();
static late TraceDio _traceDio; static late TraceDio _traceDio;
//token
String? token; String? token;
//自定义查询条件
Map<String, String> queryParameters = {};
TraceDio(Logger? logger) TraceDio(Logger? logger)
: _dio = Dio(), : _dio = Dio(),
@@ -25,6 +28,8 @@ class TraceDio {
// 设置拦截器,自动添加 traceId 和 spanId并记录日志 // 设置拦截器,自动添加 traceId 和 spanId并记录日志
_dio.interceptors.add(InterceptorsWrapper( _dio.interceptors.add(InterceptorsWrapper(
onRequest: (options, handler) { onRequest: (options, handler) {
//动态添加请求参数
options.queryParameters.addAll(queryParameters);
// 获取请求中的 traceId如果没有则生成 // 获取请求中的 traceId如果没有则生成
String? traceId = options.headers['X-Trace-ID']; String? traceId = options.headers['X-Trace-ID'];
String? spanId = options.headers['X-Span-ID']; String? spanId = options.headers['X-Span-ID'];

View File

@@ -62,6 +62,10 @@ class Redis {
return await _command?.send_object(["GET", key]); return await _command?.send_object(["GET", key]);
} }
Future<bool> delete(String key) async {
return await _command?.send_object(["DEL", key]) == "OK";
}
Future<bool> setWithExpiry(String key, String value, int ttlInSeconds) async { Future<bool> setWithExpiry(String key, String value, int ttlInSeconds) async {
var response = await _command var response = await _command
?.send_object(["SETEX", key, ttlInSeconds.toString(), value]); ?.send_object(["SETEX", key, ttlInSeconds.toString(), value]);

View File

@@ -1,4 +1,3 @@
abstract class WebServer { abstract class WebServer {
static late WebServer _webServer; static late WebServer _webServer;
@@ -10,7 +9,8 @@ abstract class WebServer {
_webServer = server; _webServer = server;
} }
void start(int port, {Function? interceptor}); void start(int port,
{Function? interceptor, TokenResult Function(String?)? tokenCheck});
void stop(); void stop();
void addHandler(handler); void addHandler(handler);
} }
@@ -58,9 +58,18 @@ class RequestMapping {
final HttpMethod method; final HttpMethod method;
final String path; final String path;
final HttpResponseType responseType; final HttpResponseType responseType;
final bool auth;
const RequestMapping( const RequestMapping(
{this.method = HttpMethod.ALL, {this.method = HttpMethod.ALL,
required this.path, required this.path,
this.auth = true,
this.responseType = HttpResponseType.JSON}); this.responseType = HttpResponseType.JSON});
} }
class TokenResult {
bool status;
String? errMsg;
Map<String, dynamic>? payload;
TokenResult({required this.status, this.errMsg, this.payload});
}

View File

@@ -60,7 +60,8 @@ class RouteGenerator extends GeneratorForAnnotation<RequestMapping> {
() { () {
return method.name; return method.name;
}, },
pl >= 2 ? 2 : 1 pl >= 2 ? 2 : 1,
anno.read("auth").boolValue
]); ]);
} }
// print("构建完毕"); // print("构建完毕");

View File

@@ -1,3 +1,4 @@
import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'package:EasyDartModule/EasyDartModule.dart'; import 'package:EasyDartModule/EasyDartModule.dart';
@@ -16,6 +17,7 @@ class ShelfWebServer implements WebServer {
final Router _router = Router(); final Router _router = Router();
final Uuid uuid = Uuid(); final Uuid uuid = Uuid();
final Map<String, WebSocketHandler> _wsCall = {}; final Map<String, WebSocketHandler> _wsCall = {};
TokenResult Function(String?)? tokenCheck;
ShelfWebServer(this.logger); ShelfWebServer(this.logger);
final String tag = "webserver"; final String tag = "webserver";
@@ -134,7 +136,9 @@ class ShelfWebServer implements WebServer {
} }
@override @override
void start(int port, {Function? interceptor}) async { void start(int port,
{Function? interceptor,
TokenResult Function(String?)? tokenCheck}) async {
//反射获取全部路由地址 //反射获取全部路由地址
var pipeline = Pipeline() var pipeline = Pipeline()
.addMiddleware(requestIdMiddleware()) .addMiddleware(requestIdMiddleware())
@@ -151,6 +155,9 @@ class ShelfWebServer implements WebServer {
}; };
}); });
} }
if (tokenCheck != null) {
this.tokenCheck = tokenCheck;
}
final handler = pipeline.addHandler(_routerHandler); final handler = pipeline.addHandler(_routerHandler);
_server = await serve(handler, InternetAddress.anyIPv4, port); _server = await serve(handler, InternetAddress.anyIPv4, port);
print('Server listening on port ${_server?.port}'); print('Server listening on port ${_server?.port}');
@@ -161,6 +168,19 @@ class ShelfWebServer implements WebServer {
_server?.close(); _server?.close();
} }
Response setResponseHeader(response, contentType) {
Map<String, String> 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 @override
void addHandler(handler) { void addHandler(handler) {
try { try {
@@ -179,33 +199,58 @@ class ShelfWebServer implements WebServer {
} }
addRouter(k, p[0], (req, [a, b, c, d, e, f]) async { addRouter(k, p[0], (req, [a, b, c, d, e, f]) async {
//从request中获取token并解码传入 //从request中获取token并解码传入
String? token = req.headers["token"]; bool auth = true;
if (p.length >= 5) {
//判断是否需要进行token校验
auth = p[4];
}
dynamic payload; dynamic payload;
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) { if (token != null) {
try { try {
payload = JWT.decode(token).payload; payload = JWT.decode(token).payload;
check = true;
} catch (e) { } catch (e) {
//jwt解码失败 //jwt解码失败
print(e); print(e);
check = false;
}
} else {
check = false;
} }
} }
var response; if (!check) {
response =
Response.ok(jsonEncode({"code": -10000, "msg": "token为空"}));
return setResponseHeader(response, p[1].type);
}
}
if (p[3] == 2) { if (p[3] == 2) {
response = await p[2](req, payload ?? <String, dynamic>{}); response = await p[2](req, payload ?? <String, dynamic>{});
} else { } else {
response = await p[2](req); response = await p[2](req);
} }
Map<String, String> headers = {...response.headers}; if (response is! Response) {
headers['Access-Control-Allow-Origin'] = '*'; //返回数据不是 Response 对象
headers['Access-Control-Allow-Headers'] = response = Response.ok(response.toString());
'Content-Type,X-Span-ID,X-Trace-ID,token'; }
headers["Access-Control-Expose-Headers"] = response = setResponseHeader(response, p[1].type);
"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);
return response; return response;
}); });
@@ -241,7 +286,8 @@ class ShelfWebServer implements WebServer {
_router.options(path, (r) { _router.options(path, (r) {
return Response.ok('', headers: { return Response.ok('', headers: {
'Access-Control-Allow-Origin': '*', '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', 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
}); });
}); });

View File

@@ -6,7 +6,8 @@ class ShelfWebServer implements WebServer {
final String tag = "webserver"; final String tag = "webserver";
ShelfWebServer(this.logger); ShelfWebServer(this.logger);
@override @override
void start(int port, {Function? interceptor}) async {} void start(int port,
{Function? interceptor, Function(String?)? tokenCheck}) async {}
@override @override
void stop() {} void stop() {}