springboot使用redis和ThreadLocal做单点登录

前面写过一篇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());
    }

 

转载于:https://my.oschina.net/u/3551274/blog/3017585

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值