当前位置: 首页 > 知识库问答 >
问题:

如何在spring cloud api网关终止请求流并重定向到不同的URL路由路径

康弘义
2023-03-14

我已经实现了以下微服务应用程序。

     $.ajax({
                type: "POST",
                enctype: 'multipart/form-data',
                url: "http://localhost:8081/api/v1/users/bulkUpload",
                xhrFields: {
                    withCredentials: true
                },
                data: newData,
                processData: false,
                contentType: false,
                crossDomain: false,
                cache: false,
                timeout: 600000,
                success: function (data) {
......
}

但是,如果刷新令牌在Ajax请求中不可用,我希望在API网关级别终止请求,并希望将用户重定向到Ui客户端注销页面(http://localhost:8080/logout)。为此,我实现了一个spring cloud gateway过滤器,如下所示。

@Component
public class AccessTokenCheckingGlobalFilterPre extends AbstractGatewayFilterFactory<AccessTokenCheckingGlobalFilterPre.Config> {

    @Value("${security.oauth2.client.client-id}")
    private String client_id;

    @Value("${security.oauth2.client.client-secret}")
    private String client_secret;

    
    
    public AccessTokenCheckingGlobalFilterPre() {
        super(AccessTokenCheckingGlobalFilterPre.Config.class);
    }

    @Override
    public GatewayFilter apply(AccessTokenCheckingGlobalFilterPre.Config config) {
        return (exchange, chain) -> {
             Route route = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);
             ServerHttpRequest request = exchange.getRequest();
             ServerHttpResponse response = exchange.getResponse();
             
             if(route!=null && request.getPath().toString().contains("oauth/token")) {
                 
                 return chain.filter(exchange.mutate().request(request).response(response).build());

             }else {
                
                 MultiValueMap<String, HttpCookie> cookies = request.getCookies();
                 List<HttpCookie> accessTokenList =  cookies.get("access_token");
                 List<HttpCookie> refreshTokenList =  cookies.get("refresh_token");
                 HttpHeaders heraders = request.getHeaders();
                 String access_token="";
                 String refresh_token = "";
                 if(accessTokenList != null) {
                   access_token = accessTokenList.get(0).getValue();
                 }
                 
                 if(refreshTokenList != null) {
                   refresh_token = refreshTokenList.get(0).getValue();
                 }

                 
                 if(access_token.isEmpty() && !refresh_token.isEmpty()) {
                     
                     RestTemplate restTemplate = new RestTemplate();
                     String credentials = client_id + ":" + client_secret;
                     String encodedCredentials = new String(Base64.encode(credentials.getBytes()));

                    HttpHeaders headers = new HttpHeaders();
                    headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
                    headers.add("Authorization", "Basic " + encodedCredentials);

                    HttpEntity<String> requestEntity = new HttpEntity<String>(headers);

                    String access_token_url = "http://localhost:8602/oauth/token";
                    access_token_url += "?grant_type=refresh_token";
                    access_token_url += "&refresh_token=" + refresh_token;

                    ResponseEntity<String> aouthResponse = restTemplate.exchange(access_token_url, HttpMethod.POST, requestEntity, String.class);
                    String responseJson = access_token = aouthResponse.getBody();
                    
                    ObjectMapper mapper = new ObjectMapper();
                    JsonNode node = null;
                    try {
                        node = mapper.readTree(responseJson);
                    } catch (JsonProcessingException e) {
                        e.printStackTrace();
                    }
                    
                    String newRefreshToken = node.path("refresh_token").asText();
                    String newAccessToken = node.path("access_token").asText();
                    int expiresIn = Integer.parseInt(node.path("expires_in").asText());
                    int refreshTokenExpireTime = Integer.parseInt(node.path("refreshTokenExpires_In").asText());

                    
                    ResponseCookie accessTokenCookie = ResponseCookie.from("access_token", newAccessToken)
                            .path("/")
                            .maxAge(expiresIn)
                            .build();
                    
                    ResponseCookie refreshTokenCookie = ResponseCookie.from("refresh_token", newRefreshToken)
                            .path("/")
                            .maxAge(refreshTokenExpireTime)
                            .build();
                    
                    response.addCookie(refreshTokenCookie);
                    response.addCookie(accessTokenCookie);
                    
                    access_token = newAccessToken;
                            
                 
                 }else if(refresh_token.isEmpty()){
                     //request.getHeaders().setLocation(URI.create("http://localhost:8080/Logout"));
                     response.setStatusCode(HttpStatus.PERMANENT_REDIRECT);
                     response.getHeaders().setLocation(URI.create("http://localhost:8080/Logout"));
                     //response.setComplete();
                     return chain.filter(exchange.mutate().request(request).response(response).build());

                 }
                 
                 final String value = access_token;
                 
                 request = request.mutate()
                         .headers(httpHeaders -> httpHeaders.add("Authorization", "Bearer  " + value))
                         .build();
                
                 
             }
             
             return chain.filter(exchange.mutate().request(request).response(response).build());

            
            
        };
    }
    

    public static class Config {

    }
}

该逻辑已被实现以检查请求中是否存在刷新令牌。除非它正在重定向Ui客户端注销页面(http://localhost:8080/logout)。

}else if(refresh_token.isEmpty()){
                     //request.getHeaders().setLocation(URI.create("http://localhost:8080/Logout"));
                     response.setStatusCode(HttpStatus.PERMANENT_REDIRECT);
                     response.getHeaders().setLocation(URI.create("http://localhost:8080/Logout"));
                     //response.setComplete();
                     return chain.filter(exchange.mutate().request(request).response(response).build());

                 }

但是,在API网关级别没有发生请求终止,请求仍然转发给用户微服务。

如何在apigateway筛选器终止请求流并重定向回ui客户端注销页面。

共有1个答案

江阳冰
2023-03-14

而不是

}else if(refresh_token.isEmpty()){
                     //request.getHeaders().setLocation(URI.create("http://localhost:8080/Logout"));
                     response.setStatusCode(HttpStatus.PERMANENT_REDIRECT);
                     response.getHeaders().setLocation(URI.create("http://localhost:8080/Logout"));
                     //response.setComplete();
                     return chain.filter(exchange.mutate().request(request).response(response).build());

             }

若要重定向用户,请使用

}else if(refresh_token.isEmpty()){
    response.setStatusCode(HttpStatus.FOUND); //302
    response
            .getHeaders()
            .set("Location", "/logout");

    return response.setComplete();

                 }
 类似资料:
  • 我正在构建一个使用react-router的web应用程序。当我点击url localhost:8080/user时,它工作得很好。当我点击localhost:8080/user/login时,它不起作用,控制台显示意外标记>这是什么意思?我不明白这个问题。 在这行代码中还有一件事,当我换到其他类时,它也不起作用。 Routes.js webpack.config.js

  • 英文原文:http://emberjs.com/guides/routing/redirection/ 过渡与重定向 在路由中调用transitionTo或者在控制器中调用transitionToRoute,将停止当前正在进行的过渡,并开启一个新的,这也用作重定向。transitionTo具有参数,其行为与link-to助手相同。 如果过渡到一个没有动态段的路由,路由的model钩子始终都会运行。

  • 我写了一个注销函数,简单地从数据库中删除所有必要的信息后,我清除会话和重定向注销。我想将用户重定向到主页(登陆页面),这在另一个功能中是登录(成功登录后,我会重定向到主页)。在我的代码中是这样做的: 路线。php有以下途径: 正如我在登录时所说的那样,我以前也这样做过,但它确实起了作用,但这里的意思是: 下面是包含重定向的登录部分的外观: 请支持并让我知道为什么它可以一次又一次地工作,尽管这两个方

  • 问题内容: 我有一些路线的角度应用程序,例如: 使用angular的html5路由模式,当您从应用程序内单击指向链接的链接时,这些链接可以正确解决,但是当您进行硬刷新时,这些链接当然会出现404错误。为了解决这个问题,我尝试实现基本的htaccess重写。 这适用于角度请求,但是当我尝试在我的域内加载脚本或进行ajax调用时,例如: 该脚本不会加载-它的请求被重定向,并且它尝试加载index.ht

  • 我正在尝试使用react router(版本^1.0.3)做一个简单的重定向到另一个视图的操作,我只是觉得有些累。 我只需要将用法发送到“/login”,就这样。 我能做什么? 控制台中的错误: 未捕获的引用错误:未定义PropType 用我的路线归档