前面写过一篇Springboot整合Redis的文章,这里就不在叙述,
整体思路即是:
写一个拦截器,对请求方法进行拦截,拦截器会从请求的header中取token信息,如果token信息不存在,则证明用户尚未登录,让用户去登录。
如果token存在则去redis中查找用户的相关信息,我习惯只讲用户的userCode和名称这些简单的信息存储在redis里。redis中查不到userInfo证明token不合法或者token是一个游客的token,同样跳转登录注册界面。如果userInfo存在,则讲userInfo存储在 ThreadLocal中,以便其他方法直接获取。
直接上代码:
1、ThreadUtils
package com.health.web.common.utils;
import com.health.web.modules.entity.UmsMember;
/**
* @author lee
* @date 2019-02-22
* @description: ThreadLocal工具类
*/
public class ThreadUtils<T> {
private static final ThreadLocal<String> tokenHolder = new ThreadLocal<>();
private static final ThreadLocal<UmsMember> userHolder = new ThreadLocal<>();
public static void setToken(String token){
tokenHolder.set(token);
}
public static String getToken(){
return tokenHolder.get();
}
public static void setUserHolder(UmsMember user){
userHolder.set(user);
}
public static UmsMember getUserHolder(){
return userHolder.get();
}
public static void remove(){
tokenHolder.remove();
userHolder.remove();
}
}
2、拦截器
package com.health.web.interceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
/**
* @author lee
* @date 2019-02-19
* @description: 添加拦截器
*/
@Configuration
public class HealthWebConfigure extends WebMvcConfigurationSupport {
@Bean
public LoginInterceptor loginInterceptor(){
return new LoginInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/thirdPartyLogin/sns")
.excludePathPatterns("/login")
.excludePathPatterns("/logout");
super.addInterceptors(registry);
}
}
package com.health.web.interceptor;
import com.health.web.common.utils.*;
import com.health.web.modules.entity.UmsMember;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author lee
* @date 2019-02-18
* @description: 登录注册登出拦截器
*/
public class LoginInterceptor implements HandlerInterceptor {
@Autowired
private RedisUtil redisUtil;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//token存在header中
String token = request.getHeader("token");
if(StringUtils.isBlank(token)){
HttpRespUtil.respContent(response,R.error(PublicResultConstant.INVALID_PARAM_EMPTY.result,PublicResultConstant.INVALID_PARAM_EMPTY.msg));
return false;
}
ThreadUtils.setToken(token);
//根据token从redis获取用户信息是否存在登录
UmsMember userInfo = (UmsMember) redisUtil.get(ConstantFunction.USER_INFO_ + token);
if(userInfo==null || StringUtils.isBlank(userInfo.getUserCode()) || userInfo.getId()==null){
HttpRespUtil.respContent(response,R.error(PublicResultConstant.UNAUTHORIZED.result,PublicResultConstant.UNAUTHORIZED.msg));
return false;
}
ThreadUtils.setUserHolder(userInfo);
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
ThreadUtils.remove();
}
}
3、Controller层用户获取信息时的方法
/**
* 列表
*/
@RequestMapping("/list")
public R list(){
UmsMember userHolder = ThreadUtils.getUserHolder();
if(userHolder!=null && StringUtils.isNotBlank(userHolder.getUserCode())){
UserDataRecord record = new UserDataRecord();
record.setUserCode(userHolder.getUserCode());
List<UserDataRecord> list = userDataRecordService.findUserDataRecord(record);
return R.ok().put("userDataRecordList",list);
}
return R.error(PublicResultConstant.PARAM_ERROR.result, PublicResultConstant.PARAM_ERROR.getMsg());
}