上一篇文章讲述了用springboot用https实现微服务的负载均衡方式。

详细可以看链接

下面这章讲述用http实现登录控制,用token作为权限认证的令牌。

一、负载均衡服务器server和client程序均和上一次的一样,如不清楚可以查看上一篇内容。

二、http的consumer服务器的编写。

     主要包含三方面程序的编写:一是登录验证账号密码,然后设置token到redis;二是设置filter过滤器,验证是否传送token,以及token保存的用户信息是否过期;三是和redis交互的程序。

1、登录验证代码:

@RestController
public class ResetController {
    @Autowired
    private UserService userService;
    @Autowired
    private RedisTokenManager redisTokenManager;

    @RequestMapping(value="/login/{username}/{password}",method = RequestMethod.GET
            ,produces = { "application/json;charset=UTF-8" })
    @ResponseBody
    public Object login(@PathVariable String username,@PathVariable String password,
                        HttpServletRequest request){
        Token tokenBean=new Token();
        UserInfo user = this.userService.login(username, password);
        if (user != null) {
        //登录成功生成token并保存token
            String userAgent = request.getHeader("user-agent");
            String token = this.redisTokenManager.getToken(user);
            tokenBean.setIsLogin(true);
            tokenBean.setToken(token);
        } else {
            tokenBean.setIsLogin(false);
        }
        return tokenBean;
    }

}

这里先通过数据服务验证用户名密码是否正确,然后保存token到redis,把token数据返回给客户端。

2、过滤器把不含token和token已经过期的数据过滤掉

@Configuration
@WebFilter
public class TokenFilter  extends OncePerRequestFilter {
    @Autowired
    private RedisTokenManager redisTokenManager;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException
    {
        if (request.getRequestURI().indexOf("/login/") >= 0) {
            filterChain.doFilter(request, response);
        }else {
            String accessToken = request.getHeader("Authorization");
            Result result = new Result();
            if (null == accessToken) {
                result.setSuccess(false);
                result.setData("token 不存在");
            } else {
                UserInfo userInfo = this.redisTokenManager.getUserInfoByToken(accessToken);
                if (userInfo != null) {
                    filterChain.doFilter(request, response);
                } else {
                    result.setSuccess(false);
                    result.setData("token已过期,请重新登录!");
                }
            }
            try {
                responseOutWithJson(response, result);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    protected void responseOutWithJson(HttpServletResponse response,
                                       Object responseObject) throws Exception{
        //将实体对象转换为JSON Object转换
        ObjectMapper mapper = new ObjectMapper();
            String jsonStr= mapper.writeValueAsString(responseObject);
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        PrintWriter out = null;
        try {
            out = response.getWriter();
            out.append(jsonStr);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                out.close();
            }
        }
    }
}

3、redis tokenmanager程序

@Service("redisTokenManager")
public class RedisTokenManager implements TokenManager {
    @Value("${spring.redis.expire}")
    private Integer expire;
    @Autowired
    private RedisUtils redisUtils;

    /**
     * 创建token
     * @param userInfo
     * @return
     */
    public String getToken(UserInfo userInfo){
        //使用uuid作为源token
        String token = UUID.randomUUID().toString().replace("-", "");
        redisUtils.set(token,userInfo,expire);
        return token;
    }

    /**
     * 刷新用户
     * @param token
     */
    public void refreshUserToken(String token){
        Object userInfo=redisUtils.get(token);
        if(userInfo!=null){
            redisUtils.set(token,userInfo,expire);
        }
    }

    /**
     * 用户退出登陆
     * @param token
     */
    public void loginOff(String token){
        redisUtils.del(token);
    }

    /**
     * 获取用户信息
     * @param token
     * @return
     */
    public UserInfo getUserInfoByToken(String token){
        Object userInfo=redisUtils.get(token);
        if(userInfo!=null){
            return (UserInfo)userInfo;
        }
        return null;
    }
}

代码github地址

顺便给大家推荐给开源客服系统,小倍客服

 

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐