Rumah >Java >javaTutorial >Cara menggunakan Spring AOP untuk melaksanakan pengesahan antara muka dalam SpringBoot
Pengaturcaraan berorientasikan aspek boleh mengekstrak logik yang tiada kaitan dengan perniagaan tetapi perlu dipanggil bersama oleh pelbagai modul perniagaan, dan memotongnya ke dalam kod dalam bentuk aspek , dengan itu mengurangkan gandingan kod dalam darjah sistem, mengurangkan kod pendua.
Spring AOP melaksanakan pengaturcaraan berorientasikan aspek melalui prakompilasi dan proksi dinamik semasa masa jalan
Penggunaan asas dinamik AOP Proksi selesai keperluan dan menjana kelas proksi untuk kelas yang perlu dipertingkatkan Terdapat dua cara untuk menjana kelas proksi (iaitu kelas yang perlu dipertingkatkan), jika:
Titik sambungan: Dalam Kaedah kelas proksi (dipertingkatkan)
Titik masuk: Kaedah yang sebenarnya perlu dipertingkatkan
Pemberitahuan: Kod logik untuk dipertingkatkan
Pra-pemberitahuan: Dilaksanakan sebelum fungsi utama dilaksanakan
Pemberitahuan siaran: Dilaksanakan selepas pelaksanaan fungsi utama
Pemberitahuan keliling: Dilaksanakan sebelum dan selepas pelaksanaan fungsi utama
Pemberitahuan pengecualian: Dilaksanakan apabila pengecualian berlaku dalam pelaksanaan fungsi tema
Pemberitahuan akhir: Fungsi utama akan dilaksanakan tanpa mengira sama ada pelaksanaan berjaya
Aspek: Gabungan titik masuk dan aspek , iaitu kaedah yang dipertingkatkan dan fungsi yang dipertingkatkan membentuk aspek
Anotasi:
@Aspect: Isytiharkan bahawa kelas ialah aspek , tulis pemberitahuan dan titik masuk
@Sebelum: Sesuai pra-pemberitahuan
@AfterReturning: Sesuai dengan post-notification
@Sekitar: Sepadan dengan pemberitahuan sekeliling
@AfterThrowing: Pemberitahuan pengecualian sepadan
@Selepas: Surat pemberitahuan akhir
@Pointcut: Pointcut Penyata, menandakannya pada kaedah boleh menjadikan ungkapan lebih ringkas
Gunakan ungkapan pointcut untuk mengisytiharkan pointcut
Konfigurasikan akaun pengesahan antara muka2 Baca konfigurasi akaunaccount: infos: - account: xinchao secret: admin
@Data public class SecretInfo { private String account; private String secret; }
@Configuration @ConfigurationProperties("account") public class SecretConfig { private List<SecretInfo> infos; private Map<String, SecretInfo> map; private Map<String, TokenInfo> tokenMap = new HashMap<>(); public void setInfos(List<SecretInfo> infos) { this.infos = infos; map = infos.stream().collect(Collectors.toMap(SecretInfo::getAccount, Function.identity())); } public synchronized String getToken(String account, String secret) { SecretInfo info = map.get(account); if (info == null) { throw new BusinessException("无效账号"); } if (!StringUtils.equals(info.getSecret(), secret)) { throw new BusinessException("无效密码"); } TokenInfo tokenInfo = tokenMap.get(account); if (tokenInfo != null && tokenInfo.getToken() != null) { return tokenInfo.getToken(); } tokenInfo = new TokenInfo(); String uuid = UUID.randomUUID().toString(); tokenInfo.setToken(uuid); tokenInfo.setCreateDate(LocalDateTime.now()); tokenInfo.setExpireDate(LocalDateTime.now().plusHours(2)); tokenMap.put(account,tokenInfo); return tokenInfo.getToken(); } public boolean checkCaptcha(String captcha) { return tokenMap.values().stream().anyMatch(e->StringUtils.equals(e.getToken(),captcha)); } }
@Data public class TokenInfo { private LocalDateTime createDate; private LocalDateTime expireDate; private String token; public String getToken() { if (LocalDateTime.now().isBefore(expireDate)) { return token; } return null; } public boolean verification(String token) { return Objects.equals(this.token, token); } }
Mula-mula, tulis anotasi untuk menunjukkan bahawa pengesahan tidak diperlukan5 >Gunakan antara muka ini untuk mencipta token dalam ingatan dan mengembalikannya ke bahagian hadapan. Kemudian, kita boleh menghantar token ini untuk pengesahan apabila melaraskan antara muka lain. Kedudukan masuk ialah medan captcha@Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface CaptchaIgnoreAop { }@Slf4j @Aspect @Component @Order(2) public class CaptchaAop { @Value("${spring.profiles.active:dev}") private String env; @Autowired private SecretConfig config; @Pointcut("execution(public * com.herenit.phsswitch.controller.impl..*.*(..))" + "&&@annotation(org.springframework.web.bind.annotation.PostMapping)" + "&&!@annotation(com.herenit.phsswitch.aop.CaptchaIgnoreAop)") public void tokenAop() { } @Around("tokenAop()") public Object doBefore(ProceedingJoinPoint joinPoint) throws Throwable { Object[] args = joinPoint.getArgs(); if (args.length == 0 || !(args[0] instanceof RequestWrapper) || "test,dev".contains(env)) { log.info("当前环境无需校验token"); return joinPoint.proceed(); } String captcha = ((RequestWrapper) joinPoint.getArgs()[0]).getCaptcha(); if (!config.checkCaptcha(captcha)) { throw new BusinessException("captcha无效"); } return joinPoint.proceed(); } }
@PostMapping("/login") @CaptchaIgnoreAop public ResponseWrapper login(@RequestBody JSONObject userInfo) { String token = config.getToken(userInfo.getString("loginName") , userInfo.getString("password")); JSONObject result = new JSONObject(); result.put("platformAccessToken", token); return ResponseWrapper.success(result); }
Atas ialah kandungan terperinci Cara menggunakan Spring AOP untuk melaksanakan pengesahan antara muka dalam SpringBoot. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!