从抽象中的回调调用抽象方法 class
Calling a abstract method from a callback inside a abstract class
我正在使用 undertow 作为我的 HTTP 库,并希望验证每个请求的 JWT 令牌和 HTTP 方法。我不想在每个 HttpHandler
中实施验证。这是正确的做法吗?
Handler.java
public abstract class Handler implements HttpHandler {
private HttpString[] methods;
Handler(HttpString... methods) {
this.methods = methods;
}
@Override
public void handleRequest(HttpServerExchange httpServerExchange) throws Exception {
// verifying HTTP method
boolean verified = false;
for (HttpString method : methods) {
if (httpServerExchange.getRequestMethod().equals(method)) {
verified = true;
break;
}
}
if (!verified) {
// return http 405, cause: invalid HTTP method
httpServerExchange.setStatusCode(StatusCodes.METHOD_NOT_ALLOWED);
httpServerExchange.getResponseSender().send(Variables.Response.EMPTY);
}
// verifying JWT token
String jwt = httpServerExchange.getRequestHeaders().get("jwt", 0);
JWT.verifyToken(jwt)
.addListener(token -> {
if (token != null) {
handleVerifiedRequest(httpServerExchange, token);
} else {
// return http 400, cause: JWT invalid
httpServerExchange.setStatusCode(StatusCodes.UNAUTHORIZED);
httpServerExchange.getResponseSender().send(Variables.Errors.INVALID_JWT);
}
});
}
public abstract void handleVerifiedRequest(HttpServerExchange httpServerExchange, String Token);
}
你好Handler.java
public class HelloHandler extends Handler {
public HelloHandler(HttpString... methods) {
super(methods);
}
@Override
public void handleVerifiedRequest(HttpServerExchange httpServerExchange, String Token) {
// .. do something
}
}
您的方法将强制子class 实现handleVerifiedRequest
,但也会允许其他人重新实现handleRequest
以规避您的验证。要防止 subclass 这样做,请将 final
关键字添加到摘要中的原始方法 class.
public abstract class Handler implements HttpHandler {
// ... //
@Override
public final void handleRequest(HttpServerExchange httpServerExchange) throws Exception {
// ... your verification code ... //
}
public abstract void handleVerifiedRequest(HttpServerExchange httpServerExchange, String Token);
}
一种更可重用和推荐的方法是坚持使用 Undertow HttpHandler API 并将处理程序链接在一起。
首先,正如您已经提议的那样,您的 JWT 身份验证处理程序检查请求中的传入令牌:
public class JwtAuthHandler implements HttpHandler {
AttachmentKey<JwtToken> JWT_TOKEN = AttachmentKey.create(JwtToken.class);
private final HttpHandler next;
public JwtAuthHandler(HttpHandler next) {
this.next = next;
}
@Override
public void handleRequest(HttpServerExchange exchange) throws Exception {
...
JWT.verifyToken(jwt)
.addListener(token -> {
if (token != null) {
exchange.putAttachment(JWT_TOKEN, token);
next.handleRequest(exchange);
} else {
// return http 400, cause: JWT invalid
httpServerExchange.setStatusCode(StatusCodes.UNAUTHORIZED);
httpServerExchange.getResponseSender().send(Variables.Errors.INVALID_JWT);
}
});
}
}
但有一个区别,它只是实现 HttpHandler 接口,并期望在成功时调用 next HttpHandler。在对下一个处理程序调用 handleRequest 方法之前,请注意添加当前有效令牌作为交换附件的行。附件是在处理程序之间传递数据的一种方式。
然后,您的 HelloHandler 只是希望从交换附件中获得一个 JwtToken(请注意,这只是一个猜测,我不知道您使用的是什么 JWT 库,这是只是示例中 token 变量的类型。)
public class HelloHandler implements HttpHandler {
@Override
public void handleRequest(HttpServerExchange exchange) throws Exception {
JwtToken token = exchange.getAttachment(JWT_TOKEN);
...
}
}
仅当请求身份验证成功时才会调用此处理程序。
您可能知道,处理程序应该链接在一起:
Undertow.builder()
.addHttpListener(8080, "0.0.0.0")
.setHandler(new JwtAuthHandler(new HelloHandler()))
.build().start();
如果您坚持使用 HttpHandler API,您可以轻松地集成和使用 Undertow 提供的现有处理程序,请查看 here。
我正在使用 undertow 作为我的 HTTP 库,并希望验证每个请求的 JWT 令牌和 HTTP 方法。我不想在每个 HttpHandler
中实施验证。这是正确的做法吗?
Handler.java
public abstract class Handler implements HttpHandler {
private HttpString[] methods;
Handler(HttpString... methods) {
this.methods = methods;
}
@Override
public void handleRequest(HttpServerExchange httpServerExchange) throws Exception {
// verifying HTTP method
boolean verified = false;
for (HttpString method : methods) {
if (httpServerExchange.getRequestMethod().equals(method)) {
verified = true;
break;
}
}
if (!verified) {
// return http 405, cause: invalid HTTP method
httpServerExchange.setStatusCode(StatusCodes.METHOD_NOT_ALLOWED);
httpServerExchange.getResponseSender().send(Variables.Response.EMPTY);
}
// verifying JWT token
String jwt = httpServerExchange.getRequestHeaders().get("jwt", 0);
JWT.verifyToken(jwt)
.addListener(token -> {
if (token != null) {
handleVerifiedRequest(httpServerExchange, token);
} else {
// return http 400, cause: JWT invalid
httpServerExchange.setStatusCode(StatusCodes.UNAUTHORIZED);
httpServerExchange.getResponseSender().send(Variables.Errors.INVALID_JWT);
}
});
}
public abstract void handleVerifiedRequest(HttpServerExchange httpServerExchange, String Token);
}
你好Handler.java
public class HelloHandler extends Handler {
public HelloHandler(HttpString... methods) {
super(methods);
}
@Override
public void handleVerifiedRequest(HttpServerExchange httpServerExchange, String Token) {
// .. do something
}
}
您的方法将强制子class 实现handleVerifiedRequest
,但也会允许其他人重新实现handleRequest
以规避您的验证。要防止 subclass 这样做,请将 final
关键字添加到摘要中的原始方法 class.
public abstract class Handler implements HttpHandler {
// ... //
@Override
public final void handleRequest(HttpServerExchange httpServerExchange) throws Exception {
// ... your verification code ... //
}
public abstract void handleVerifiedRequest(HttpServerExchange httpServerExchange, String Token);
}
一种更可重用和推荐的方法是坚持使用 Undertow HttpHandler API 并将处理程序链接在一起。
首先,正如您已经提议的那样,您的 JWT 身份验证处理程序检查请求中的传入令牌:
public class JwtAuthHandler implements HttpHandler {
AttachmentKey<JwtToken> JWT_TOKEN = AttachmentKey.create(JwtToken.class);
private final HttpHandler next;
public JwtAuthHandler(HttpHandler next) {
this.next = next;
}
@Override
public void handleRequest(HttpServerExchange exchange) throws Exception {
...
JWT.verifyToken(jwt)
.addListener(token -> {
if (token != null) {
exchange.putAttachment(JWT_TOKEN, token);
next.handleRequest(exchange);
} else {
// return http 400, cause: JWT invalid
httpServerExchange.setStatusCode(StatusCodes.UNAUTHORIZED);
httpServerExchange.getResponseSender().send(Variables.Errors.INVALID_JWT);
}
});
}
}
但有一个区别,它只是实现 HttpHandler 接口,并期望在成功时调用 next HttpHandler。在对下一个处理程序调用 handleRequest 方法之前,请注意添加当前有效令牌作为交换附件的行。附件是在处理程序之间传递数据的一种方式。
然后,您的 HelloHandler 只是希望从交换附件中获得一个 JwtToken(请注意,这只是一个猜测,我不知道您使用的是什么 JWT 库,这是只是示例中 token 变量的类型。)
public class HelloHandler implements HttpHandler {
@Override
public void handleRequest(HttpServerExchange exchange) throws Exception {
JwtToken token = exchange.getAttachment(JWT_TOKEN);
...
}
}
仅当请求身份验证成功时才会调用此处理程序。
您可能知道,处理程序应该链接在一起:
Undertow.builder()
.addHttpListener(8080, "0.0.0.0")
.setHandler(new JwtAuthHandler(new HelloHandler()))
.build().start();
如果您坚持使用 HttpHandler API,您可以轻松地集成和使用 Undertow 提供的现有处理程序,请查看 here。