sofastack / sofa-rpc

SOFARPC is a high-performance, high-extensibility, production-level Java RPC framework.
https://www.sofastack.tech/sofa-rpc/docs/Home
Apache License 2.0
3.83k stars 1.18k forks source link

如何在Filter中透传数据 #165

Closed eonezhang closed 6 years ago

eonezhang commented 6 years ago

Question

如何在Filter中知道透传数据

Scenes

目前要实现一个服务的鉴权功能,希望通过Filter来实现,结合数据透传方案

RpcInvokeContext.getContext().putRequestBaggage("key_request","value_request");
String requestValue=RpcInvokeContext.getContext().getRequestBaggage("key_request");

现在的问题是在Filter中无法获取透传值 token

 public SofaResponse invoke(FilterInvoker invoker, SofaRequest request) {
        RpcInternalContext context = RpcInternalContext.getContext();
        RpcInvokeContext invokeContext = RpcInvokeContext.getContext();
        if (context.isProviderSide()) {
            String token = invokeContext.getRequestBaggage("token"); // 这里获取到的值是null
            if ("123456".equals(token)) {
                return invoker.invoke(request);
            } else {
                SofaResponse resp = new SofaResponse();
                resp.setErrorMsg("ERR-403");
                return resp;
            }
        } else {
            invokeContext.putRequestBaggage("token", "123456");
            SofaResponse response = invoker.invoke(request);
            if ("ERR-403".equals(response.getErrorMsg())) {
                throw new SofaRpcException(RpcErrorType.UNKNOWN, "Token not found");
            }
            return response;
        }
    }
leizhiyuan commented 6 years ago

可以查看注解

@AutoActive(providerSide = true)

providerSide=true 表示服务端.否则是客户端.

eonezhang commented 6 years ago

@leizhiyuan 为了让问题更加明确,我将问题内容修改了下。 现在可以通过RpcInternalContext得知Filter是在哪端被调用,但是无法获取数据透传的值 有什么方式可以在Filter中获取透传的值呢?

leizhiyuan commented 6 years ago

https://github.com/alipay/sofa-rpc/wiki/Invoke-Chain-Pass-Data 应该是有的才对. 能否提供复现的 demo?

eonezhang commented 6 years ago

链路数据透传的示例代码对业务代码有侵入性,经过进一步阅读代码,发现在可以使用SofaRequest来完成我的需求,以下是源码:

@Extension("auth")
@AutoActive(providerSide = true, consumerSide = true)
public class AuthFilter extends Filter {

    @Override
    public SofaResponse invoke(FilterInvoker invoker, SofaRequest request) {
        RpcInternalContext context = RpcInternalContext.getContext();
        if (context.isProviderSide()) {
            String token = (String) request.getRequestProp("token");
            if ("123456".equals(token)) {
                return invoker.invoke(request);
            } else {
                SofaResponse resp = new SofaResponse();
                resp.setErrorMsg("ERR-403");
                return resp;
            }
        } else {
            request.addRequestProp("token", "123456");
            SofaResponse response = invoker.invoke(request);
            if ("ERR-403".equals(response.getErrorMsg())) {
                throw new SofaRpcException(RpcErrorType.UNKNOWN, "Token not found");
            }
            return response;
        }
    }
}
leizhiyuan commented 6 years ago

@eonezhang ok, 这种是之前我们推荐的一种,业务方之前是更希望直接在业务代码中引入,所以我们给出的示例是通过上下文, filter 是我们更推荐的.