SpringBoot AOPカット+Redis認証


成熟したプロジェクトの中で、ログインIDに制限がある方法があれば、ユーザーのIDを検証することがよくあります.方法は簡単です.Cookieから私たちのアイデンティティ情報を取り出して、有効かどうかを判断することです.
ここで使用している認証ツールはRedisです.ユーザー登録時にtokenを生成し、tokenをCookieに入れてフロントエンドに転送すると同時にRedisにtokenを保存します.
1.有効期間、接頭辞などのRedis用の属性クラスを作成する
/**
 * @author:    
 * @date: 2018/8/2
 * @description:
 */

public interface RedisConstant {

    String TOKEN_PREFIX = "token_";

    Integer EXPIRE = 7200; // 2  

}

2.loginメソッドでtokenを生成し、CookieとRedisにtokenを保存する
    @GetMapping("/login")
    public ModelAndView login(@RequestParam("openid") String openid,
                              HttpServletResponse response,
                              Map map){
        // 1.openid            
        SellerInfo sellerInfo = sellerService.findSellerByOpenid(openid);
        if(sellerInfo == null){
            map.put("msg",ResultEnum.LOGIN_FAIL.getMsg());
            map.put("url","/sell/seller/order/list");
            return new ModelAndView("common/error");
        }
        // 2.  token  redis
        String token = UUID.randomUUID().toString();
        Integer expire = RedisConstant.EXPIRE;
        System.out.println("token = "+token);
        redisTemplate.opsForValue().set(String.format(RedisConstant.TOKEN_PREFIX + token),openid,expire, TimeUnit.SECONDS);
        // 3.  token  cookie
        CookieUtil.set(response,CookieConstant.TOKEN,token,expire);
        return new ModelAndView("redirect:" + projectUrlConfig.getSell() + "/sell/seller/order/list");
    }

ここでredisのsetメソッドはそれぞれkey(keyは生成されたtoken)、value(ユーザのidなどアイデンティティを判別するためのデータ)、有効時間を伝達する
TimeUnit.SECONDSはRedisに時間の単位を計算することを教えます
3.logoutメソッドでRedisとCookieをクリアする
    @GetMapping("/logout")
    public ModelAndView logout(HttpServletRequest request,
                       HttpServletResponse response,
                       Mapmap){
        // 1. cookie  token
        Cookie cookie = CookieUtil.get(request,CookieConstant.TOKEN);
        if(cookie != null){
            // 2.  redis
            redisTemplate.opsForValue().getOperations().delete(String.format(RedisConstant.TOKEN_PREFIX + cookie.getValue()));
            // 3.  cookie
            CookieUtil.set(response,CookieConstant.TOKEN,null,0);
        }
        map.put("msg",ResultEnum.LOGOUT_SUCCESS.getMsg());
        map.put("url","/sell/seller/order/list");
        return new ModelAndView("common/success",map);

    }

アイデンティティの設定について説明しましたが、どうやって認証しますか?認証が必要な方法が多い場合、各方法で手動で認証を行うことはできません.明らかに、認証は共有をカプセル化できるはずです.
AOPカット技術を用いて実現した
第1歩:接点を確立して、中のexecutionの中で方法を濾過して、persを意味します.lyt.sell.controller.Sellerは接頭辞のパッケージの下のすべてのクラスのすべてのpublicメソッドですが、SellerUserControllerのメソッドは含まれていません.この接点は上でフィルタされたすべてのメソッドに有効です.次のメソッドverify()は、すべてのカットするメソッドを表します.
    @Pointcut("execution(public * pers.lyt.sell.controller.Seller*.*(..))" +
    "&& !execution(public * pers.lyt.sell.controller.SellerUserController.*(..))")
    public void verify() {
    }

ステップ2:カットメソッドを記述し、@Before注記のメソッドは、カットメソッドの実行前に実行されます.これは認証に最適です.
@Before("verify()")
public void doVerify(){
    ...
}

完全なAOPクラスは以下の通りです.
/**
 *       
 * @author:    
 * @date: 2018/8/2
 * @description:
 */
@Aspect
@Component
@Slf4j
public class SellerAuthorizeAspect {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Pointcut("execution(public * pers.lyt.sell.controller.Seller*.*(..))" +
    "&& !execution(public * pers.lyt.sell.controller.SellerUserController.*(..))")
    public void verify() {
    }

    @Before("verify()")
    public void doVerify(){
        //   request
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        //  cookie
        Cookie cookie = CookieUtil.get(request,CookieConstant.TOKEN);
        if(cookie == null){
            log.warn("【    】 Cookie    token");
            throw new SellerAuthorizeException();
        }

        String tokenValue = redisTemplate.opsForValue().get(String.format(RedisConstant.TOKEN_PREFIX+cookie.getValue()));
        if(StringUtils.isEmpty(tokenValue)){
            log.warn("【    】 Redis    token");
            throw new SellerAuthorizeException();
        }
    }
}

では、カットされたすべてのメソッドが実行される前に、上のログインチェックだけが考えられます.