ในฐานะบริการเกตเวย์ Zuul เป็นสถานีขนส่งภายนอกสำหรับบริการอื่น ๆ และคำขอจะถูกส่งต่อผ่าน Zuul สิ่งนี้เกี่ยวข้องกับข้อมูลบางอย่างไม่สามารถส่งคืนได้อย่างสมบูรณ์เช่นข้อมูลรับรองสำหรับการสื่อสารระหว่างบริการข้อมูลการเข้ารหัสผู้ใช้ ฯลฯ
ตัวอย่างเช่นบริการผู้ใช้ให้อินเทอร์เฟซเข้าสู่ระบบ หลังจากชื่อผู้ใช้และรหัสผ่านถูกต้องโทเค็นจะถูกส่งคืน โทเค็นนี้ใช้เป็นผ่านบริการผู้ใช้ จากนั้นโทเค็นจะกลับมาหลังจากที่ผู้ใช้เข้าสู่ระบบได้สำเร็จจะต้องมีการเข้ารหัสหรือป้องกันไม่ให้มีการดัดแปลง ก่อนที่จะมาถึงอินเทอร์เฟซอื่น ๆ ของบริการผู้ใช้โทเค็นจะต้องได้รับการตรวจสอบ โทเค็นที่ผิดกฎหมายไม่จำเป็นต้องส่งต่อไปยังบริการผู้ใช้และข้อมูลสามารถส่งคืนได้โดยตรงที่เลเยอร์เกตเวย์
ในการแก้ไขข้อมูลที่ส่งคืนโดยบริการคุณต้องใช้ตัวกรองของ Zuul เมื่อใช้งานคุณจะต้องสืบทอด Zuulfilter และใช้วิธีการที่จำเป็น
Zuul จัดเตรียมตัวกรองสี่ประเภทเริ่มต้นซึ่งจะถูกระบุด้วยวิธี FilterType
ลำดับที่ตัวกรองถูกเรียกใช้จะถูกจัดเรียงโดยวิธีตัวกรองและยิ่งค่าที่เล็กลงเท่าไหร่ก็ยิ่งต้องการมากขึ้นเท่านั้น FilterConstants กำหนดลำดับการดำเนินการและประเภทการกำหนดเส้นทางของคอลัมน์บางคอลัมน์ของตัวกรองเริ่มต้นและค่าคงที่ส่วนใหญ่ที่ต้องใช้อยู่ที่นี่
ดังที่แสดงในตัวอย่างจำเป็นต้องมีการสกัดกั้นอินเทอร์เฟซเข้าสู่ระบบดังนั้นจึงจำเป็นต้องใช้เฉพาะคำขอเข้าสู่ระบบ (/ผู้ใช้/เข้าสู่ระบบ) คุณสามารถใช้วิธีการฟิลเตอร์ของตัวกรองเพื่อตรวจสอบว่าจำเป็นต้องมีการสกัดกั้นหรือไม่
เนื่องจากการปรับเปลี่ยนข้อมูลเกิดขึ้นหลังจากการบริการผู้ใช้สำเร็จประเภทการสกัดกั้นจึงเป็นประเภทโพสต์ การดำเนินการของทั้งชั้นเรียนมีดังนี้:
AuthResponseFilter ระดับสาธารณะขยาย Abstractzuulfilter {สตริงสุดท้ายคงที่แบบคงที่ response_key_token = "โทเค็น"; @Value ("$ {system.config.authfilter.authurl}") สตริงส่วนตัว Authurl; @Value ("$ {system.config.authfilter.tokenkey}") สตริงส่วนตัว tokenkey = response_key_token; @autowired Authapi Authapi; @Override บูลีนสาธารณะควร filter () {requestcontext context = getCurrentContext (); return stringutils.equals (context.getRequest (). getRequesturi (). toString (), authurl); } @Override วัตถุสาธารณะรัน () {ลอง {requestContext context = getCurrentContext (); stream inputstream = context.getResponsEdatastream (); String body = streamutils.copytoString (สตรีม, charset.forName ("UTF-8")); if (stringutils.isnotblank (body)) {gson gson = new gson (); @suppresswarnings ("ไม่ได้ตรวจสอบ") แผนที่ <สตริง, สตริง> result = gson.fromjson (body, map.class); if (stringutils.isnotblank (result.get (tokenkey))) {AuthModel Authresult = authapi.encodetoken (result.get (tokenkey)); if (authresult.getStatus ()! = httpservletResponse.sc_ok) {โยน unlegalargumentException ใหม่ (authresult.geterrmsg ()); } String AccessToken = AuthResult.getToken (); result.put (tokenkey, accesstoken); } body = gson.tojson (ผลลัพธ์); } context.setResponseBody (ร่างกาย); } catch (ioexception e) {rethrowruntimeException (e); } return null; } @Override Public String FilterType () {return filterConstants.post_type; } @Override public int filterOrder () {return filterConstants.send_response_filter_order - 2; - ในไฟล์การกำหนดค่าเพิ่ม URL ที่ได้รับอนุญาตและส่งคืนโทเค็นคีย์:
System.config.authfilter.authurl =/ผู้ใช้/เข้าสู่ระบบ
System.config.authfilter.tokenkey = โทเค็น
Context.setResponseBody (ร่างกาย); รหัสนี้เป็นหลักและข้อมูลที่ส่งคืนจะถูกแก้ไขด้วยวิธีนี้
เมื่อผู้ใช้เข้าสู่ระบบในความสำเร็จการเข้ารหัสโทเค็นจะดำเนินการผ่านบริการที่ได้รับอนุญาตตามโทเค็นที่ส่งคืน วิธีการเข้ารหัสที่นี่ใช้ JWT เพื่อป้องกันไม่ให้ผู้ใช้การดัดแปลงข้อมูลการร้องขอที่ผิดกฎหมายสามารถสกัดกั้นโดยตรงที่เลเยอร์เกตเวย์
เกี่ยวกับกระบวนการดำเนินการของตัวกรอง Zuul ไม่จำเป็นต้องอธิบายที่นี่ คุณสามารถบอกซอร์สโค้ดได้อย่างรวดเร็ว ZuulservletFilter:
@Override โมฆะสาธารณะ dofilter (servletrequest servletrequest, servletResponse servletResponse, filterChain filterChain) พ่น IOException, servletexception {ลอง {init ((httpservletRequest) servletRequest, ลอง {prerouting (); } catch (zuulexception e) {ข้อผิดพลาด (e); Postrouting (); กลับ; } // ส่งต่อไปยังห่วงโซ่เท่านั้นหากการตอบกลับของ Zuul ไม่ถูกส่งถ้า (! requestcontext.getCurrentContext (). sendzuulResponse ()) {filterchain.dofilter (servletrequest, servletResponse); กลับ; } ลอง {การกำหนดเส้นทาง (); } catch (zuulexception e) {ข้อผิดพลาด (e); Postrouting (); กลับ; } ลอง {postRouting (); } catch (zuulexception e) {ข้อผิดพลาด (zuulexception ใหม่ (e, 500, "uncaught_exception_from_filter_" + e.getClass (). getName ())); } ในที่สุด {requestcontext.getCurrentContext (). unSet (); -คำอธิบายวิธี:
การส่งต่อที่ร้องขอสามารถยกเลิกได้ผ่านบริบท SetsendzuulResponse (เท็จ) แต่สามารถตั้งค่าได้ในตัวกรองก่อนประเภทเท่านั้น
เกี่ยวกับวิธีการยกเลิกตัวกรอง:
เฉพาะตัวกรองก่อนประเภทที่รองรับการส่งต่อการยกเลิกการยกเลิกและตัวกรองอื่น ๆ จะถูกดำเนินการตามลำดับ ยิ่งไปกว่านั้นตัวกรองก่อนประเภทสามารถยุติการส่งต่อหลังจากตัวกรองก่อนประเภททั้งหมดจะถูกดำเนินการ ตัวกรองไม่สามารถยกเลิกและดำเนินการต่อไปได้ ดูซอร์สโค้ด ZuulservletFilter:
// ส่งต่อไปยังห่วงโซ่หากการตอบกลับของ Zuul ไม่ถูกส่งถ้า (! requestcontext.getCurrentContext (). sendzuulResponse ()) {filterchain.dofilter (servletRequest, servletResponse); กลับ; - รหัสในบทความนี้ถูกส่งไปที่: https://gitee.com/cmlbeliev/springcloud ยินดีต้อนรับสู่ดาว
การใช้งานคลาสใน: com.cml.springcloud.api.filter.authresponsefilter ภายใต้โครงการ Api-Getway
ที่อยู่ท้องถิ่น: http://xz.vevb.com:81/201806/yuanma/cmmlbeliev-springcloud_jb51.rar
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น