Tocken認証ログイン


  :
          ,           tocken  redis,        。              tocken  ,       tocken    。    ,  redis  tocken

    :springboot  
pom.xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-redis</artifactId>
    <version>1.4.1.RELEASE</version>
</dependency>


-------------------  controller

    @Autowired
    private TokenHelper tokenHelper;

    @NoneAuth
    @GetMapping("/login")
    public Object login(String username, String password,Integer id) {
        //     username,password,id   User    
        if(username == null || !password.equals("123")) {
            return JsonData.buildError(HttpStatusEnum.NOT_FOUND.getCode(), MessageConstant.USERNAME_OR_PASSWORD_ERROR);
        }
        //          ,  token
        TokenModel model = tokenHelper.create(id);
        return JsonData.buildSuccess(model);
    }

    /**    
     * tocken     id
     * @param request
     * @return
     */
    @DeleteMapping
    public Object logout(HttpServletRequest request) {
        Integer userId = (Integer) request.getAttribute(NormalConstant.CURRENT_USER_ID);
        if(userId != null) {
            tokenHelper.delete(userId);
        }
        return JsonData.buildSuccess();
    }
}

------------------------tocken Model  tocken  ,     id tocken
public class TokenModel {
    private Integer userId;

    private String token;

    public TokenModel(Integer userId, String token) {
        this.userId = userId;
        this.token = token;
    }

    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    public String getToken() {
        return token;
    }

    public void setToken(String token) {
        this.token = token;
    }

    @Override
    public String toString() {
        return "TokenModel [userId=" + userId + ", token=" + token + "]";
    }

}


------  tocken------------tockenhelper  token redis       

public interface TokenHelper {
    /**
     *     id  token
     * @param id
     * @return
     */
    TokenModel create(Integer id);

    /**
     *        token
     * @param model
     * @return
     */
    boolean check(TokenModel model);

    /**
     *               token
     * @param authStr
     * @return
     */
    TokenModel get(String authStr);

    /**
     *     id  token
     * @param mode
     * @return
     */
    boolean delete(Integer id);
}


--------------------- tockenhelper    

@Component
public class RedisTokenHelp implements TokenHelper {
    @Autowired
    private RedisClient redisClient;

    @Override
    public TokenModel create(Integer id) {
        String token = UUID.randomUUID().toString().replace("-", "");
        TokenModel mode = new TokenModel(id, token);
        redisClient.set(id == null ? null : String.valueOf(id), token, RedisClient.TOKEN_EXPIRES_SECOND);
        return mode;
    }

    @Override
    public boolean check(TokenModel model) {
        boolean result = false;
        if(model != null) {
            String userId = model.getUserId().toString();
            String token = model.getToken();
            String authenticatedToken = redisClient.get(userId);
            if(authenticatedToken != null && authenticatedToken.equals(token)) {
                redisClient.expire(userId, RedisClient.TOKEN_EXPIRES_SECOND);
                result = true;
            }
        }
        return result;
    }

    @Override
    public TokenModel get(String authStr) {
        TokenModel model = null;
        if(StringUtils.isNotEmpty(authStr)) {
            String[] modelArr = authStr.split("_");
            if(modelArr.length == 2) {
                int userId = Integer.parseInt(modelArr[0]);
                String token = modelArr[1];
                model = new TokenModel(userId, token);
            }
        }
        return model;
    }

    @Override
    public boolean delete(Integer id) {
        return redisClient.remove(id == null ? null : String.valueOf(id));
    }
}

----------------------redis          ,    

@Component
public class RedisClient { //   redis tocken       
    public static final long TOKEN_EXPIRES_SECOND = 1800;// 

    @Autowired
    private StringRedisTemplate redisTpl;

    /**
     *  redis   
     * @param key    a:b:id      rdm    redis                ,    
     * @param value
     * @return
     */
    public boolean set(String key, String value) {
        boolean result = false;
        try {
            redisTpl.opsForValue().set(key, value);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }


    /**
     *  redis   ,        
     * @param key
     * @param value
     * @param time
     * @return
     */
    public boolean set(String key, String value, long time) {
        boolean result = false;
        try {
            redisTpl.opsForValue().set(key, value);
            expire(key, time);
            result =  true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     *   redis   
     * @param key
     * @return
     */
    public String get(String key) {
        String result = null;
        try {
            result = redisTpl.opsForValue().get(key);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;

    }

    /**
     *   key     
     * @param key
     * @param time
     * @return
     */
    public boolean expire(String key, long time) {
        boolean result = false;
        try {
            if(time > 0) {
                redisTpl.expire(key, time, TimeUnit.SECONDS);
                result = true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     *   key    value
     * @param key
     * @return
     */
    public boolean remove(String key) {
        boolean result = false;
        try {
            redisTpl.delete(key);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
}

-----------------------        

public enum HttpStatusEnum {
    SUCCESS(200, "    "), BAD_REQUEST(400, "      "), UNAUTHORIZED(401, "     "),
    FORBIDDEN(403, "    "), NOT_FOUND(404, "     "), INTERNAL_SERVER_ERROR(500, "     ");

    private int code;
    private String info;

    private HttpStatusEnum(int code, String info) {
        this.code = code;
        this.info = info;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getInfo() {
        return info;
    }

    public void setInfo(String info) {
        this.info = info;
    }

    public static HttpStatusEnum getInfoByCode(int code) {
        for(HttpStatusEnum status :values()) {
            if(status.getCode() == code) {
                return status;
            }
        }
        return null;
    }
}


---------------------     ,controller     ,       
/**
 *                 
 * @author baipengfei
 *
 */
@Documented
@Retention(RUNTIME)
@Target(METHOD)
public @interface NoneAuth {

}



------------------------      

//      
@Component
public class LoginInterceptor extends HandlerInterceptorAdapter {
    @Autowired
    private TokenHelper tokenHelper;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        System.out.println("      ");
        //              
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        //   @NoneAuth           ,    
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        if(method.getAnnotation(NoneAuth.class) != null) return true;
        //token  
        String authStr = request.getHeader(NormalConstant.AUTHORIZATION);
        TokenModel model = tokenHelper.get(authStr);

        //    
        if(tokenHelper.check(model)) {
            request.setAttribute(NormalConstant.CURRENT_USER_ID, model.getUserId());
            return true;
        }
        //     
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        response.getWriter().write(JsonUtils.obj2String(JsonData.buildError(401, "     ")));
        return false;
    }
}



-------------------------     ,      
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {//     ,    

    @Autowired
    LoginInterceptor loginInterceptor;
    public void addInterceptors(InterceptorRegistry registry) {
        //  TestInterceptor   
        InterceptorRegistration registration = registry.addInterceptor(loginInterceptor);
        registration.addPathPatterns("/**");                    //        

    }
}


-------------------------------
              redis   <key value> = <userid  tocken>{
    "code": 200,
    "data": {
        "userId": 11123,
        "token": "55af99e971184acda806ae4d6186f716"
    },
    "msg": "    "
}

      tocken,header    authStr    userid_tocken 
 :
11123_55af99e971184acda806ae4d6186f716