Solve the problem of feign remote call request header loss:

Question 1: Solve the problem of feign remote call verification failure:

After we access Spring Security, we will bring the JWT token in the header when requesting, so that we can access resources. Assume such a scenario: the authentication of the authentication service has been completed, the header of the front-end page now carries the JWT token, the front-end needs to access the A service, and in the A service, it needs to remotely call the B service through Feign, A, B The services are all connected to Spring Security. The following is an illustration:
insert image description here

  1. When the front end requests the A service, the token is included in the header, because the A service requires authentication, and the authentication is passed.
  2. Service A calls service B remotely. If no processing is done, service B also needs authentication. At this time, service A cannot successfully call service B. Because the request of service A does not have a token, it cannot pass the authentication of service B and will be rejected. Spring Security intercepts it, causing the call to fail.

At this time, you can think of a way to keep the token passed in the header:

  1. Set the Feign client's authentication token using the global configuration: You can set the authentication token in the Feign client's global configuration, so that every Feign request will automatically include the token. In your A service, create a Feign configuration class and RequestInterceptorset the "Authorization" header with , adding the JWT token to every Feign request. In this way, no matter which remote service A service calls, it will automatically bring the authentication token.
package com.ds.user.config;

import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

@Configuration
public class FeignConfig implements RequestInterceptor {
    
    
    @Override
    public void apply(RequestTemplate requestTemplate) {
    
    

        // 在您的代码中获取JWT令牌的逻辑
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String token = request.getHeader("token");
        // 从当前请求的上下文中获取JWT令牌
//        String token = // 获取JWT令牌的逻辑,例如从请求的Header中获取

        System.out.println("我是token  我被调用了");
        // 将JWT令牌添加到Feign请求的Header中
        if (token != null) {
    
    
            requestTemplate.header("token",token);
        }
    }
}

accomplish:
insert image description here

Question 2: Solve the problem of multi-threaded feign remote call verification failure:

first step:

We want to use InheritableThreadLocal to store token

In a multi-threaded environment, ThreadLocalthe value of is independent among different threads and cannot be shared. This means that the value you set in one thread tokencannot be directly retrieved in another thread.

To achieve sharing in a multi-threaded environment token, you may consider using InheritableThreadLocalinstead ThreadLocalto store tokenvalues. InheritableThreadLocalAllows child threads to inherit tokenthe value of the parent thread. This way, when you set it in the parent thread token, the child thread will be able to get the correct tokenvalue.

First define a utils class:

public class TokenHolder {
    
    
    private static final InheritableThreadLocal<String> tokenHolder = new InheritableThreadLocal<>();

    public static String getToken() {
    
    
        return tokenHolder.get();
    }

    public static void setToken(String token) {
    
    
        tokenHolder.set(token);
    }

    public static void clearToken() {
    
    
        tokenHolder.remove();
    }
}

Step two:

Before we use multithreading, we can store the token in tokenHolder. Just call the setToken method in it

third step:

Then, use it in the method FeignConfigto get the value: (can be used in conjunction with the above)applyTokenHolder.getToken()token

public class FeignConfig implements RequestInterceptor {
    
    
    @Override
    public void apply(RequestTemplate requestTemplate) {
    
    
        String token = TokenHolder.getToken();
        // ...
        // 添加其他逻辑
        // ...
    }
}

Guess you like

Origin blog.csdn.net/qq_63946922/article/details/130812251