SpringBoot 經過token進行身份驗證,存儲redis

代碼:html

public interface TokenManager {

    /**
     * 建立token
     * @param userInfo
     * @return
     */
    String getToken(UserInfo userInfo);

    /**
     * 刷新用戶
     * @param token
     */
    void refreshUserToken(String token);

    /**
     * 用戶退出登錄
     * @param token
     */
    void loginOff(String token);

    /**
     * 獲取用戶信息
     * @param token
     * @return
     */
    UserInfo getUserInfoByToken(String token);

}

具體實現:redis

@Component
public class RedisTokenManager implements TokenManager {

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private GlobalConfig globalConfig;

    /**
     * 建立token
     * @param userInfo
     * @return
     */
    public String getToken(UserInfo userInfo){
        //使用uuid做爲源token
        String token = UUID.randomUUID().toString().replace("-", "");
        String token_format=String.format(Constants.TOKEN_FORMAT,token);
        redisUtils.set(token_format,userInfo,globalConfig.getTokenExpires());
        return token;
    }

    /**
     * 刷新用戶
     * @param token
     */
    public void refreshUserToken(String token){
        token=String.format(Constants.TOKEN_FORMAT,token);
        if(redisUtils.exists(token)){
            redisUtils.setExpireTime(token, globalConfig.getTokenExpires());
        }
    }

    /**
     * 用戶退出登錄
     * @param token
     */
    public void loginOff(String token){
         token=String.format(Constants.TOKEN_FORMAT,token);
         redisUtils.remove(token);
    }

    /**
     * 獲取用戶信息
     * @param token
     * @return
     */
    public UserInfo getUserInfoByToken(String token){
        token=String.format(Constants.TOKEN_FORMAT,token);
        if(redisUtils.exists(token)){
            return (UserInfo)redisUtils.get(token);
        }
        return null;
    }
}

對TokenManager進行二次封裝,每次操做不須要token參數dom

@Component
public class AuthManager {

    @Autowired
    private TokenManager tokenManager;

    /**
     * 獲取請求體
     * @return
     */
    public HttpServletRequest getRequest(){
        return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    }

    /**
     * 登陸
     * @param userInfo
     * @return
     */
    public String signIn(UserInfo userInfo){
        return tokenManager.getToken(userInfo);
    }

    /**
     * 獲取該訪問用戶信息
     * @return
     */
    public UserInfo getUserInfo(){
        HttpServletRequest request=getRequest();
        String token=request.getAttribute(Constants.USER_TOKEN).toString();
        UserInfo userInfo=tokenManager.getUserInfoByToken(token);
        if(userInfo==null){
            throw new AuthException("該用戶已過時", HttpStatus.UNAUTHORIZED.value());
        }
        return userInfo;
    }

    /**
     * 刷新該登陸用戶,延時
     */
    public void refreshUserInfo(){
        HttpServletRequest request=getRequest();
        String token=request.getAttribute(Constants.USER_TOKEN).toString();
         tokenManager.refreshUserToken(token);
    }

    /**
     * 註銷該訪問用戶
     */
    public void loginOff(){
        HttpServletRequest request=getRequest();
        String token=request.getAttribute(Constants.USER_TOKEN).toString();
        tokenManager.loginOff(token);
    }
}

上面是對用戶信息基本操做ide

對用戶進行控制,部分接口能夠不登錄訪問ui

@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AuthIgnore {

}

攔截器:spa

@Component
public class AuthorizationInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        AuthIgnore annotation;
        if(handler instanceof HandlerMethod) {
            annotation = ((HandlerMethod) handler).getMethodAnnotation(AuthIgnore.class);
        }else{
            return true;
        }

        //若是有@AuthIgnore註解,則不驗證token
        if(annotation != null){
            return true;
        }

        //獲取用戶憑證
        String token = request.getHeader(Constants.USER_TOKEN);
        if(StringUtils.isBlank(token)){
            token = request.getParameter(Constants.USER_TOKEN);
        }
        if(StringUtils.isBlank(token)){
            Object obj = request.getAttribute(Constants.USER_TOKEN);
            if(null!=obj){
                token=obj.toString();
            }
        }

        //token憑證爲空
        if(StringUtils.isBlank(token)){
            throw new AuthException(Constants.USER_TOKEN + "不能爲空", HttpStatus.UNAUTHORIZED.value());
        }

        return true;
    }
}

若是token參數必須放在請求體中,直接讀取請求體會報錯,requestbody misscode

解決方法:http://www.javashuo.com/article/p-tflplwns-bo.htmlorm

這裏的註解只是標註那些不須要登錄的接口htm

上面相關redis操做在上面也寫過,請看前面文章。blog

相關文章
相關標籤/搜索