SpringBoot AOPカット+Redis認証
4624 ワード
成熟したプロジェクトの中で、ログインIDに制限がある方法があれば、ユーザーのIDを検証することがよくあります.方法は簡単です.Cookieから私たちのアイデンティティ情報を取り出して、有効かどうかを判断することです.
ここで使用している認証ツールはRedisです.ユーザー登録時にtokenを生成し、tokenをCookieに入れてフロントエンドに転送すると同時にRedisにtokenを保存します.
1.有効期間、接頭辞などのRedis用の属性クラスを作成する
2.loginメソッドでtokenを生成し、CookieとRedisにtokenを保存する
ここでredisのsetメソッドはそれぞれkey(keyは生成されたtoken)、value(ユーザのidなどアイデンティティを判別するためのデータ)、有効時間を伝達する
TimeUnit.SECONDSはRedisに時間の単位を計算することを教えます
3.logoutメソッドでRedisとCookieをクリアする
アイデンティティの設定について説明しましたが、どうやって認証しますか?認証が必要な方法が多い場合、各方法で手動で認証を行うことはできません.明らかに、認証は共有をカプセル化できるはずです.
AOPカット技術を用いて実現した
第1歩:接点を確立して、中のexecutionの中で方法を濾過して、persを意味します.lyt.sell.controller.Sellerは接頭辞のパッケージの下のすべてのクラスのすべてのpublicメソッドですが、SellerUserControllerのメソッドは含まれていません.この接点は上でフィルタされたすべてのメソッドに有効です.次のメソッドverify()は、すべてのカットするメソッドを表します.
ステップ2:カットメソッドを記述し、@Before注記のメソッドは、カットメソッドの実行前に実行されます.これは認証に最適です.
完全なAOPクラスは以下の通りです.
では、カットされたすべてのメソッドが実行される前に、上のログインチェックだけが考えられます.
ここで使用している認証ツールは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();
}
}
}
では、カットされたすべてのメソッドが実行される前に、上のログインチェックだけが考えられます.