REST token 找到用户,然后找到用户资源
但总不能每个方法都去调用token验证的方法在进入controller前集中处理,用 Interceptor实现
-
由于根据token
interceptor实现:
/** * 验证token有效性 */ @Component public class AccessTokenVerifyInterceptor extends HandlerInterceptorAdapter { @Resource UserService userService; private final static Logger LOG = LoggerFactory.getLogger(AccessTokenVerifyInterceptor.class); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { LOG.debug("AccessTokenVerifyInterceptor executing......."); boolean flag = false; //accesstoken 参数 String accessToken = request.getParameter("accesstoken"); if(StringUtils.notEmpty(accessToken)) { //验证accessToken //verifyAccessToken 已做缓存处理 User user = userService.verifyAccessToken(accessToken); if(user!=null){ flag = true; //塞到request中去,供controller里面调用 request.setAttribute(SystemConstants.SESSION_NAME_USER,user); } } if(!flag){ response.setStatus(HttpStatus.FORBIDDEN.value()); response.getWriter().print("wrong token"); } return flag; } }
然后到spring配置文件中加上这个拦截器:
<!--过滤器--> <mvc:interceptors> <!--API TOKEN INTERCEPTOR--> <mvc:interceptor> <mvc:mapping path="/api/**"/> <mvc:exclude-mapping path="/**/api/user/**" /> <mvc:exclude-mapping path="/**/api/accesstoken" /> <bean class="cn.ifengkou.athena.controller.interceptor.AccessTokenVerifyInterceptor"></bean> </mvc:interceptor> <!--other interceptor --> </mvc:interceptors>
缓存处理
pom.xml中加入ehcache包:(spring集成ehcache ,需要spring-context和spring-context-support)
<dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache</artifactId> <version>2.10.0</version> </dependency>
加入ehcache.xml,大部分都是默认,参考springside里面说的,改了updateCheck="false",
<ehcache updateCheck="false" monitoring="autodetect" dynamicConfig="true"> <diskStore path="java.io.tmpdir" /> <cache name="accessTokenUser" maxEntriesLocalHeap="10000" maxEntriesLocalDisk="1000" eternal="false" diskSpoolBufferSizeMB="20" timeToIdleSeconds="300" timeToLiveSeconds="600" memoryStoreEvictionPolicy="LFU" transactionalMode="off"> <persistence strategy="localTempSwap" /> </cache> </ehcache>
开启缓存,在spring配置文件中加入:
<!-- 缓存配置 --> <!-- 启用缓存注解功能(请将其配置在Spring主配置文件中) --> <cache:annotation-driven cache-manager="cacheManager" /> <!-- Spring自己的基于java.util.concurrent.ConcurrentHashMap实现的缓存管理器(该功能是从Spring3.1开始提供的) --> <!-- <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager"> <property name="caches"> <set> <bean name="myCache" class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean"/> </set> </property> </bean> --> <!-- 若只想使用Spring自身提供的缓存器,则注释掉下面的两个关于Ehcache配置的bean,并启用上面的SimpleCacheManager即可 --> <!-- Spring提供的基于的Ehcache实现的缓存管理器 --> <bean id="cacheManagerFactory" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"> <property name="configLocation" value="classpath:ehcache.xml" /> </bean> <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager"> <property name="cacheManager" ref="cacheManagerFactory" /> </bean>
对verifyAccessToken 方法做缓存处理,也就是在原有方法上加Cacheable注解:
@Cacheable(value = "accessTokenUser",key = "#accessToken") @Override public User verifyAccessToken(String accessToken) { LOG.debug("verifyAccessToken executing......"); List<User> users = userDao.getUserByAccessToken(accessToken); if(users.size()!=1){ if(users.size()>1){ LOG.error("accessToken 出现了重复,bug!请检查!"); } return null; } return users.get(0); }
开始run出现
-
2015-12-04 15:25:56,531 INFO [cn.ifengkou.athena.controller.interceptor.AccessTokenVerifyInterceptor] - <AccessTokenVerifyInterceptor executing.......> 2015-12-04 15:25:56,628 INFO [cn.ifengkou.athena.service.impl.UserServiceImpl] - <verifyAccessToken executing......> 2015-12-04 15:26:21,838 INFO [cn.ifengkou.athena.controller.interceptor.AccessTokenVerifyInterceptor] - <AccessTokenVerifyInterceptor executing.......> 2015-12-04 15:26:29,184 INFO [cn.ifengkou.athena.controller.interceptor.AccessTokenVerifyInterceptor] - <AccessTokenVerifyInterceptor executing.......>
-
如有token无效,查出来User为null,cache 把null也缓存起来了