Como servicio de puerta de enlace, Zuul es una estación de tránsito externa para otros servicios, y las solicitudes se envían a través de Zuul. Esto implica que algunos datos no se pueden devolver intactos, como credenciales para la comunicación entre servicios, información de cifrado de usuario, etc.
Por ejemplo, el servicio de usuario proporciona una interfaz de inicio de sesión. Después de que el nombre de usuario y la contraseña sean correctos, se devuelve un token. Este token se usa como un pase para el servicio de usuario. Luego, el token regresó después de que el usuario inicie sesión con éxito, debe ser encriptado o impedido de manipular. Antes de llegar a otras interfaces del servicio de usuario, el token debe ser verificado. Los tokens ilegales no necesitan enviarse al servicio del usuario, y la información puede devolverse directamente a la capa de puerta de enlace.
Para modificar la información devuelta por el servicio, debe utilizar el filtro de Zuul. Al usarlo, solo necesita heredar Zuulfilter e implementar los métodos necesarios.
Zuul proporciona los cuatro tipos de filtro predeterminados, que se identifican mediante el método FilterType.
El orden en el que se ejecutan los filtros se clasifica mediante el método FilterOrge, y cuanto menor sea el valor, más preferido es. FilterConstants define la orden de ejecución y el tipo de enrutamiento de algunas columnas de filtros predeterminados, y la mayoría de las constantes que deben usarse están aquí.
Como se muestra en el ejemplo, solo la interfaz de inicio de sesión debe interceptarse, por lo que solo se necesita la solicitud de inicio de sesión (/usuario/inicio de sesión). Puede usar el método de Filter del filtro para determinar si se requiere una intercepción.
Dado que la modificación de datos se realiza después de que el servicio del usuario es exitoso, el tipo de interceptor es el tipo de publicación. La implementación de toda la clase es la siguiente:
public class AuthReSponseFilter extiende AbstractZuulfilter {String final estática privada Respuesta_Key_Token = "Token"; @Value ("$ {system.config.authfilter.authurl}") private string authurl; @Value ("$ {system.config.authfilter.tokenkey}") privado cadena tokenkey = respuesta_key_token; @AUtowired private authapi authapi; @Override public boolean deberíafilter () {requestContext context = getCurrentContext (); return stringUtils.equals (context.getRequest (). getRequesturi (). toString (), authurl); } @Override public object run () {try {requestContext context = getCurrentContext (); InputStream stream = context.getResponseDataStream (); String body = streamUtils.copyToString (stream, charset.forname ("utf-8")); if (stringUtils.isnotblank (cuerpo)) {gson gson = new gson (); @SupessWarnings ("sin verificar") mapa <string, string> result = gson.fromjson (cuerpo, map.class); if (stringUtils.isnotblank (resultado.get (tokenkey))) {authModel authResult = authapi.encodeToken (result.get (tokenkey)); if (authResult.getStatus ()! = httpservletResponse.sc_ok) {lanzar nueva ilegalArgumentException (authResult.getErrmsg ()); } String accessToken = authResult.getToken (); resultado.put (Tokenkey, AccessToken); } cuerpo = gson.tojson (resultado); } context.setResponseBody (cuerpo); } catch (ioException e) {rethrowrUntimeException (e); } return null; } @Override public string filtType () {return FilterConstants.post_type; } @Override public int filterOrder () {return FilterConstants.send_Response_Filter_order - 2; }} En el archivo de configuración, agregue la URL de autorización y devuelva el token clave:
system.config.authfilter.authurl =/user/inicio de sesión
system.config.authfilter.tokenkey = token
context.setResponseBody (cuerpo); Este código es central y los datos devueltos se modifican a través de este método.
Cuando el usuario inicia sesión con éxito, el cifrado de token se realiza a través de servicios autorizados basados en el token devuelto. El método de cifrado aquí usa JWT. Para evitar que los usuarios manipulen información, las solicitudes ilegales pueden interceptarse directamente en la capa de puerta de enlace.
Con respecto al proceso de ejecución del filtro Zuul, no hay necesidad de explicarlo aquí. Puede saber de un vistazo el código fuente. Zuulservletfilter:
@Override public void dofilter (ServLetRequest ServLetRequest, ServLetResponse ServletResponse, FilterChain FilterChain) arroja ioexception, servletException {try {init ((httpservletRequest) ServletRequest, (httpServletResponse) servletResponse); intente {preprouting (); } catch (ZuulException e) {error (e); postruting (); devolver; } // Solo reenvía a la cadena si no se envía una respuesta de Zuul si (! RequestContext.getCurrentContext (). SendzuulResponse ()) {filterChain.dofilter (servletRequest, servletResponse); devolver; } try {enrutamiento (); } catch (ZuulException e) {error (e); postruting (); devolver; } try {postrouting (); } Catch (ZuulException e) {error (Nueva ZuulException (E, 500, "Unsppaging_Exception_From_Filter_" + e.getClass (). getName ())); } Finalmente {requestContext.getCurrentContext (). Unset (); }}Descripción del método:
El reenvío solicitado se puede terminar a través del contexto.
Sobre cómo terminar el filtro:
Solo los filtros previos al tipo de reenvío de terminación de la terminación, y otros filtros se ejecutan en secuencia. Además, los filtros previos al tipo solo pueden finalizar el reenvío después de que se ejecuten todos los filtros previos al tipo. El filtro no se puede terminar y la ejecución continua. Mire el código fuente de ZuulservletFilter:
// Solo reenvía a la cadena si no se envía una respuesta Zuul if (! RequitContext.getCurrentContext (). SendzuulResponse ()) {filterChain.dofilter (servletRequest, servletResponse); devolver; } El código en este artículo se ha enviado a: https://gitee.com/cmlbeliev/springcloud bienvenido a Star
Implementación de la clase en: com.cml.springcloud.api.filter.authResponseFilter bajo el proyecto API-getway
Dirección local: http://xz.vevb.com:81/201806/yuanma/cmmlbeliev-springcloud_jb51.rar
Lo anterior es todo el contenido de este artículo. Espero que sea útil para el aprendizaje de todos y espero que todos apoyen más a Wulin.com.