springboot使用redis和ThreadLocal作單點登陸

前面寫過一篇Springboot整合Redis的文章,這裏就不在敘述,     java

總體思路便是:web

寫一個攔截器,對請求方法進行攔截,攔截器會從請求的header中取token信息,若是token信息不存在,則證實用戶還沒有登陸,讓用戶去登陸。redis

若是token存在則去redis中查找用戶的相關信息,我習慣只講用戶的userCode和名稱這些簡單的信息存儲在redis裏。redis中查不到userInfo證實token不合法或者token是一個遊客的token,一樣跳轉登陸註冊界面。若是userInfo存在,則講userInfo存儲在 ThreadLocal中,以便其餘方法直接獲取。spring

直接上代碼:apache

一、ThreadUtilsapp

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();
    }

}

二、攔截器ide

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();
    }

}

 

三、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());
    }
相關文章
相關標籤/搜索