当前位置:网站首页>RestTemplate、Feign实现Token传递

RestTemplate、Feign实现Token传递

2022-07-06 06:08:00 雪峰.贵


Fegin 方式

客户端与服务端

一、加依赖

<dependency>
   <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

二、定义注解

public @interface CheckLogin {
    
}

三、定义切面


import com.itmuch.contentcenter.util.JwtOperator;
import io.jsonwebtoken.Claims;
import lombok.RequiredArgsConstructor;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

@Aspect //切面注解
@Component
@RequiredArgsConstructor(onConstructor = @__(@Autowired))

public class CheckLoginAspect {
    


    private final JwtOperator jwtOperator;

    //AOP的Advice(before,after returning,after throwing,around)的其中一个
    @Around("@annotation(com.itmuch.contentcenter.auth.CheckLogin)")//加了@CheckLogin的方法都会走到这里
    public Object checkLogin(ProceedingJoinPoint point) throws Throwable {
    
        checkToken();
        return point.proceed();
    }


    private void checkToken() {
    
        try {
    
            // 1. 从header里面获取token
            HttpServletRequest request = getHttpServletRequest();

            String token = request.getHeader("X-Token");

            // 2. 校验token是否合法&是否过期;如果不合法或已过期直接抛异常;如果合法放行
            Boolean isValid = jwtOperator.validateToken(token);
            if (!isValid) {
    
                throw new SecurityException("Token不合法!");
            }

            // 3. 如果校验成功,那么就将用户的信息设置到request的attribute里面
            Claims claims = jwtOperator.getClaimsFromToken(token);
            request.setAttribute("id", claims.get("id"));
            request.setAttribute("wxNickname", claims.get("wxNickname"));
            request.setAttribute("role", claims.get("role"));
        } catch (Throwable throwable) {
    
            throw new SecurityException("Token不合法");
        }
    }

    private HttpServletRequest getHttpServletRequest() {
    
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes attributes = (ServletRequestAttributes) requestAttributes;
        return attributes.getRequest();
    }
}

四、客户端创建Fegin的拦截器


import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

public class TokenRelayRequestIntecepor implements RequestInterceptor {
    
    @Override
    public void apply(RequestTemplate requestTemplate) {
    
        // 1. 从header里面获取token
        HttpServletRequest request = getHttpServletRequest();

        String token = request.getHeader("X-Token");
        if(!StringUtils.isEmpty(token)){
    
            requestTemplate.header("X-Token",token);
        }
    }


    private HttpServletRequest getHttpServletRequest() {
    
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes attributes = (ServletRequestAttributes) requestAttributes;
        return attributes.getRequest();
    }
}

四、客户端加配置

feign:
  client:
    config:
      default: #全局
        loggerLevel: full
        requestInterceptors:
          - com.itmuch.contentcenter.feignclient.interceptor.TokenRelayRequestIntecepor

五、测试

传入客户端token,token会通过Fegin的拦截器把token加上。
所有Fegin的接口都会带上token

RestTemplate方式

1.创建RestTemplate的拦截器


import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

public class RestTemplateRequestInterceptor implements ClientHttpRequestInterceptor {
    
    @Override
    public ClientHttpResponse intercept(HttpRequest httpRequest, byte[] body, ClientHttpRequestExecution clientHttpRequestExecution) throws IOException {
    
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes attributes = (ServletRequestAttributes) requestAttributes;
        HttpServletRequest request = attributes.getRequest();
        String token = request.getHeader("X-Token");

        HttpHeaders headers = httpRequest.getHeaders();
        headers.add("X-Token", token);

        // 保证请求继续执行
        return clientHttpRequestExecution.execute(httpRequest, body);
    }
}

2.RestTemplate实例

@Bean
    @LoadBalanced
    @SentinelRestTemplate(
            blockHandler = "handleBlock",
            fallback = "handleFallback",
            fallbackClass = SentinelBlockHandler.class,
            blockHandlerClass = SentinelBlockHandler.class)
    public RestTemplate restTemplate(){
    
        //把配置的拦截器加到实例里
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.setInterceptors(
                Collections.singletonList(new RestTemplateRequestInterceptor())
        );
        return restTemplate;
    }
原网站

版权声明
本文为[雪峰.贵]所创,转载请带上原文链接,感谢
https://blog.csdn.net/Tiny_Demon/article/details/125106993