簡體   English   中英

如何將數據從gRPC攔截器傳遞到服務方法調用?

[英]How to pass data from gRPC interceptor to service method call?

我需要從ServerAuthIntereptor傳遞一些數據以進行調用。

ServerAuthInterceptor:

// used in context parameters map
private static final String AUTH_CONTEXT = "authContext";
private static final Context.Key<Object> AUTH_CONTEXT_KEY = Context.key(AUTH_CONTEXT);

// ...

@Override
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(
    ServerCall<ReqT, RespT> call, Metadata headers, ServerCallHandler<ReqT, RespT> next) {

    // check credentials from header

    // remember account and session token for usage later (eg. in logout)
    AuthContext authContext = new AuthContext();
    authContext.account = account;
    authContext.sessionToken = sessionToken;

    logger.info("Call {} allowed (account={}, authContext={})",
        new Object[] { call, account, authContext });

    Context context = Context
        .current()
        .withValue(AUTH_CONTEXT_KEY, authContext);

    return Contexts.interceptCall(context, call, headers, next);
}

// ...

/**
 * To be used from services
 * @return
 */
public static Account getCurrentContextAccount() {
    AuthContext authContext = (AuthContext) Context.current().key(AUTH_CONTEXT).get();
    return authContext.account;
}

在某些服務方法實現中,我嘗試從當前上下文訪問存儲的“ authContext”:

@Override
public void list(ListRequest request, StreamObserver<ListResponse> responseObserver) {
    logger.info("Starting list({}) ...", request);

     // ...

     account = ServerAuthInterceptor.getCurrentContextAccount();

但是authContext為null 有時它在工作,所以我相信它與線程(本地)有關。

正確的做法是什么?

由於某種原因,它不能在AuthContext類中使用,但是如果我分別傳遞2個上下文值,則它可以使用:

ServerAuthInterceptor:

Context context = Context
        .current()
        .withValue(AUTH_TOKEN_KEY, sessionToken)
        .withValue(AUTH_ACCOUNT_KEY, account);

服務電話:

/**
 * To be used from services
 * @return
 */
public static Account getCurrentContextAccount() {
    return (Account) AUTH_ACCOUNT_KEY.get();
}

/**
 * To be used from services
 * @return
 */
public static String getCurrentContextSessionToken() {
    return (String) AUTH_TOKEN_KEY.get();
}

上下文鍵使用引用相等。 因此,您必須使用相同的鍵實例進行設置和獲取。

這段代碼重新創建了密鑰,因此它不匹配:

Context.current().key(AUTH_CONTEXT).get();

相反,它應該是:

AUTH_CONTEXT_KEY.get();

使用引用相等,因此您可以像使用ThreadLocal一樣,將常規Java可見性(公共,受保護,程序包私有,私有)規則應用於該值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM