今天突發奇想,oauth2的模式能不能也像session一樣,每次訪問後按照訪問時間來延長accessToken的過期時間呢,代碼是在攔截器中實現的,如下:
package com.vvvv.config;
import java.util.Date;
import java.util.Objects;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import cn.hutool.cache.Cache;
import cn.hutool.cache.CacheUtil;
import cn.hutool.core.util.StrUtil;
/**
* 延長Token的有效期,達到類似Session的效果
* @author yuxuan
*
*/
@Component
public class OauthTokenInterceptor implements HandlerInterceptor {
@Autowired
private TokenStore tokenStore;
//OAUTH 緩存 默認爲3分鐘
private Cache<String, Integer> timedCache = CacheUtil.newTimedCache(1000*60*3);
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
String authorization = request.getHeader("Authorization");
if(StrUtil.isNotEmpty(authorization)) {
authorization = authorization.substring(authorization.indexOf("Bearer")+6).trim();
if(timedCache.containsKey(authorization)) {
int count = timedCache.get(authorization);
if(count % 30 == 0) {
DefaultOAuth2AccessToken token = (DefaultOAuth2AccessToken) tokenStore.readAccessToken(authorization);
if(!Objects.isNull(token) && token.isExpired()) {
//已經過期了,直接返回
return HandlerInterceptor.super.preHandle(request, response, handler);
}
Date expiration = token.getExpiration();
//給Token增加3個小時的延長期限
expiration.setTime(expiration.getTime() + (60 * 1000 * 60 * 3));
// expiration.setTime(expiration.getTime() - (60 * 1000 * 60 * 300));
token.setExpiration(expiration);
OAuth2Authentication authentication = tokenStore.readAuthentication(token);
tokenStore.storeAccessToken(token, authentication);
timedCache.remove(authorization); //移除掉
}
//次數+1
timedCache.put(authorization, timedCache.get(authorization)+1);
}else {
timedCache.put(authorization, 1); //第一次賦值爲1
}
}
return HandlerInterceptor.super.preHandle(request, response, handler);
}
}
完了之後在Spring環境中把攔截器配置上即可,有問題可以在下面評論,技術問題可以私聊我。