欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

如何在SpringBoot中使用Spring-AOP實(shí)現(xiàn)接口鑒權(quán)

 更新時(shí)間:2022年09月28日 16:55:51   作者:心潮的滴滴  
這篇文章主要介紹了如何在SpringBoot中使用Spring-AOP實(shí)現(xiàn)接口鑒權(quán),文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,感興趣的小伙伴可以參考一下

面向切面編程

面向切面編程,可以將與業(yè)務(wù)無(wú)關(guān)但是需要被各個(gè)業(yè)務(wù)模塊共同調(diào)用的邏輯抽取出來(lái),以切面的方式切入到代碼中,從而降低系統(tǒng)中代碼的耦合度,減少重復(fù)的代碼。

Spring AOP是通過(guò)預(yù)編譯方式和運(yùn)行期間動(dòng)態(tài)代理實(shí)現(xiàn)程序面向切面編程

AOP的底層原理實(shí)現(xiàn)

AOP底層使用動(dòng)態(tài)代理完成需求,為需要增加增強(qiáng)功能的類來(lái)生成代理類,有兩種生成代理類的方式,對(duì)于被代理類(即需要增強(qiáng)的類),如果:

  • 實(shí)現(xiàn)了接口,使用JDK動(dòng)態(tài)代理,生成的代理類會(huì)使用其接口沒(méi)有實(shí)現(xiàn)接口,
  • 使用CGlib動(dòng)態(tài)代理,生成的代理類會(huì)集成被代理類

AOP的相關(guān)術(shù)語(yǔ)

  • 連接點(diǎn):被代理(被增強(qiáng))的類中的方法
  • 切入點(diǎn):實(shí)際上需要被增強(qiáng)的方法
  • 通知:要增強(qiáng)的邏輯代碼
    • 前置通知:在主體功能執(zhí)行之前執(zhí)行
    • 后置通知:在主題功能執(zhí)行之后執(zhí)行
    • 環(huán)繞通知:在主體功能執(zhí)行前后執(zhí)行
    • 異常通知:在主題功能執(zhí)行出現(xiàn)異常時(shí)執(zhí)行
    • 最終通知:主體功能無(wú)論執(zhí)行是否成功都會(huì)執(zhí)行
  • 切面:切入點(diǎn)和切面的結(jié)合,即被增強(qiáng)的方法和增強(qiáng)的功能組成切面

相關(guān)注解以及切入點(diǎn)表達(dá)式

注解:

  • @Aspect: 聲明某個(gè)類是切面,編寫通知、切入點(diǎn)
  • @Before: 對(duì)應(yīng)前置通知
  • @AfterReturning: 對(duì)應(yīng)后置通知
  • @Around: 對(duì)應(yīng)環(huán)繞通知
  • @AfterThrowing: 對(duì)應(yīng)異常通知
  • @After: 對(duì)應(yīng)最終通知
  • @Pointcut: 聲明切入點(diǎn),標(biāo)注在一個(gè)方法上可以讓表達(dá)式更簡(jiǎn)潔

使用切入點(diǎn)表達(dá)式聲明切入點(diǎn)

  • execution([權(quán)限修飾符][返回類型][類完全路徑].[方法名稱][參數(shù)列表類型])

execution(* com.xxx.ABC.add()),對(duì)ABC類的方法進(jìn)行增強(qiáng)

實(shí)現(xiàn)接口鑒權(quán)

1. 配置yml文件

配置接口鑒權(quán)賬密

account:
  infos:
    - account: xinchao
      secret: admin

2. 讀取賬密配置

@Data
public class SecretInfo {
    private String account;
    private String secret;
}

3.編寫接口鑒權(quán)方法

@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("無(wú)效賬號(hào)");
        }
        if (!StringUtils.equals(info.getSecret(), secret)) {
            throw new BusinessException("無(wú)效密碼");
        }
        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);
    }
}

4. 編寫AOP

首先,編寫一個(gè)注解來(lái)標(biāo)識(shí)不需要鑒權(quán)

@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("當(dāng)前環(huán)境無(wú)需校驗(yàn)token");
            return joinPoint.proceed();
        }
        String captcha = ((RequestWrapper) joinPoint.getArgs()[0]).getCaptcha();
        if (!config.checkCaptcha(captcha)) {
            throw new BusinessException("captcha無(wú)效");
        }
        return joinPoint.proceed();
    }

}

5.編寫接口測(cè)試

@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);
}

通過(guò)這個(gè)接口,我們可以在內(nèi)存中生成一個(gè)token,同時(shí)也會(huì)返回給前端。之后我們?cè)谡{(diào)其他接口時(shí)傳入這個(gè)token進(jìn)行鑒權(quán)即可。傳入的位置是captcha字段

public class RequestWrapper<T> implements Serializable {

    private static final long serialVersionUID = 8988706670118918321L;
    public RequestWrapper() {
        super();
    }

    private T args;

    private String captcha;

    private String funcode;

    public T getArgs() {
        return args;
    }

    public void setArgs(T args) {
        this.args = args;
    }

    public String getCaptcha() {
        return captcha;
    }

    public void setCaptcha(String captcha) {
        this.captcha = captcha;
    }

    public String getFuncode() {
        return funcode;
    }

    public void setFuncode(String funcode) {
        this.funcode = funcode;
    }
}

到此這篇關(guān)于如何在SpringBoot中使用Spring-AOP實(shí)現(xiàn)接口鑒權(quán)的文章就介紹到這了,更多相關(guān) SpringBoot Spring-AOP 接口鑒權(quán)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 如何使用Spring MVC的消息轉(zhuǎn)換器設(shè)置日期格式

    如何使用Spring MVC的消息轉(zhuǎn)換器設(shè)置日期格式

    這篇文章主要介紹了如何使用Spring MVC的消息轉(zhuǎn)換器設(shè)置日期格式,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-07-07
  • Java中通過(guò)反射實(shí)現(xiàn)代理Proxy代碼實(shí)例

    Java中通過(guò)反射實(shí)現(xiàn)代理Proxy代碼實(shí)例

    這篇文章主要介紹了Java中通過(guò)反射實(shí)現(xiàn)代理Proxy代碼實(shí)例,java實(shí)現(xiàn)代理可以通過(guò)java.lang.reflect.Proxy接口結(jié)合java.lang.reflect.InvocationHandler來(lái)實(shí)現(xiàn),需要的朋友可以參考下
    2023-08-08
  • java如何將map數(shù)據(jù)存入到實(shí)體類對(duì)象中

    java如何將map數(shù)據(jù)存入到實(shí)體類對(duì)象中

    在Java編程中,經(jīng)常需要將Map集合中的數(shù)據(jù)轉(zhuǎn)換為實(shí)體類對(duì)象,這可以通過(guò)反射機(jī)制實(shí)現(xiàn),即通過(guò)遍歷Map對(duì)象,使用反射根據(jù)鍵名對(duì)應(yīng)實(shí)體類的屬性名,動(dòng)態(tài)調(diào)用setter方法將值設(shè)置到實(shí)體對(duì)象中,這樣的操作使得數(shù)據(jù)從Map結(jié)構(gòu)轉(zhuǎn)移到了具體的JavaBean中,便于后續(xù)的操作和管理
    2024-09-09
  • Spring自定義參數(shù)解析器代碼實(shí)例

    Spring自定義參數(shù)解析器代碼實(shí)例

    這篇文章主要介紹了Spring自定義參數(shù)解析器代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • 教你如何用Eclipse創(chuàng)建一個(gè)Maven項(xiàng)目

    教你如何用Eclipse創(chuàng)建一個(gè)Maven項(xiàng)目

    這篇文章主要介紹了教你如何用Eclipse創(chuàng)建一個(gè)Maven項(xiàng)目,文中有非常詳細(xì)的代碼示例,對(duì)正在入門Java的小伙伴們是非常有幫助的喲,需要的朋友可以參考下
    2021-05-05
  • Java漢字轉(zhuǎn)拼音工具類完整代碼實(shí)例

    Java漢字轉(zhuǎn)拼音工具類完整代碼實(shí)例

    這篇文章主要介紹了java漢字轉(zhuǎn)拼音工具類完整代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • java基礎(chǔ)之方法詳解

    java基礎(chǔ)之方法詳解

    這篇文章主要介紹了java基礎(chǔ)之方法詳解,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java基礎(chǔ)的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-04-04
  • 詳解Mybatis動(dòng)態(tài)sql

    詳解Mybatis動(dòng)態(tài)sql

    MyBatis的動(dòng)態(tài)SQL是基于OGNL表達(dá)式的,它可以幫助我們方便的在SQL語(yǔ)句中實(shí)現(xiàn)某些邏輯。本文給大家介紹Mybatis動(dòng)態(tài)sql小結(jié),感興趣的朋友參考下
    2016-04-04
  • Java 獲取當(dāng)前系統(tǒng)時(shí)間的三種方法

    Java 獲取當(dāng)前系統(tǒng)時(shí)間的三種方法

    這篇文章主要介紹了Java 獲取當(dāng)前系統(tǒng)時(shí)間的三種方法,幫助大家利用Java處理時(shí)間,感興趣的朋友可以了解下
    2020-10-10
  • SpringBoot配置多個(gè)數(shù)據(jù)源超簡(jiǎn)單步驟(連接多個(gè)數(shù)據(jù)庫(kù))

    SpringBoot配置多個(gè)數(shù)據(jù)源超簡(jiǎn)單步驟(連接多個(gè)數(shù)據(jù)庫(kù))

    公司項(xiàng)目有連接多個(gè)不同數(shù)據(jù)庫(kù)的需求,特研究了一下,根據(jù)網(wǎng)上的資料,這篇文章主要給大家介紹了關(guān)于SpringBoot配置多個(gè)數(shù)據(jù)源(連接多個(gè)數(shù)據(jù)庫(kù))的相關(guān)資料,需要的朋友可以參考下
    2024-05-05

最新評(píng)論