Spring AOP を使用して SpringBoot にインターフェイス認証を実装する方法
May 19, 2023 pm 06:13 PMアスペクト指向プログラミング
アスペクト指向プログラミングは、ビジネスとは関係がないが、さまざまなビジネス モジュールから共同で呼び出す必要があるロジックを抽出し、それをアスペクトの形式でコードに切り込むことができます。これにより、システム内のコードの結合が軽減され、重複コードが削減されます。
Spring AOP は、実行時のプリコンパイルと動的プロキシを通じてアスペクト指向プログラミングを実装します
AOP の基礎となる原理が実装されます
基礎となる使用法AOP は動的です プロキシは要件を満たし、拡張が必要なクラスのプロキシ クラスを生成します。プロキシ クラスを生成するには 2 つの方法があります。プロキシ クラス (つまり、拡張が必要なクラス) の場合、
- #インターフェースが実装されており、JDK 動的プロキシが使用されている場合、生成されたプロキシ クラスはそのインターフェースを使用します。インターフェースが実装されていない場合、
- CGlib ダイナミック プロキシが使用されている場合、生成されるプロキシ クラスは統合プロキシ クラスになります
-
接続ポイント:プロキシされた (拡張された) クラスのメソッド
エントリ ポイント:実際に拡張する必要があるメソッド
通知: 強化されるロジック コード
事前通知: 実行前に実行されます。メイン関数
投稿通知: テーマ関数の実行後に実行
- ## サラウンド通知:
メイン関数の実行前後に実行されます
- 例外通知:
テーマ関数の実行で例外が発生した場合に実行されます
#最終通知: - main 関数は、実行が成功したかどうかに関係なく実行されます
関連コメントとポイントカット式
@Aspect:
- 特定のクラスがアスペクトであることを宣言し、通知とエントリ ポイントを記述します
-
@Before:
対応する事前通知 -
@AfterReturning:
事後通知に対応 -
@Around:
周囲の通知に対応 -
#@AfterThrowing:
例外通知に対応 -
#@変更後:
最終通知に対応 -
@ポイントカット:
ステートメントのポイントカットをメソッド上でマークすると、式がより簡潔になります -
ポイントカット式を使用してポイントカットを宣言します
execution([権限修飾子][戻り値の型][完全なクラス パス]。 [メソッド名][パラメータリストの種類])
execution(* com.xxx.ABC.add())、ABCクラスのメソッドを拡張
インターフェースを実装認証
1. yml ファイルの構成
インターフェイス認証アカウントの構成account: infos: - account: xinchao secret: admin
2. アカウントとパスワードの構成の読み取り3. インターフェース認証メソッドを記述します@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); } }
4. AOP を記述します
最初に、認証が必要ないことを示すアノテーションを記述します@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(); } }
5. インターフェイス testを作成します。このインターフェイスを使用してメモリ内にトークンを作成し、それをフロントエンドに返します。後で、他のインターフェイスを調整するときに、認証のためにこのトークンを渡すことができます。渡される場所はキャプチャフィールドです@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); }ログイン後にコピー
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; } }
以上がSpring AOP を使用して SpringBoot にインターフェイス認証を実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

人気の記事

人気の記事

ホットな記事タグ

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











Spring Boot と OpenAI の出会いによる新しいプログラミング パラダイム

Spring Boot と Spring AI を使用して生成人工知能アプリケーションを構築する

Spring プロジェクトでの JUnit 単体テスト フレームワークの適用
