SpringBoot中如何防止接口数据泄露

SpringBoot中如何使用jwt来保护接口数据

大神们:这是我在实际工作中实际使用的,写下来与君分享,没有多漂亮的排版,没有多牛逼的技术,但是都是实在实能够解决问题的。如果你有更好的方法,还请多多指教,共同进步。如果喜欢这类的文章,关注我哈。也可以去我的博客看(vsalw.com)----vsalw

SpringBoot中如何防止接口数据泄露

在使用springboot能够很方便的写接口,但是这些接口都是暴漏出来的,没有安全验证,任何人都可以调用显然这是不合理的。如果加个注册登录模块,只有登陆的用户才能调用,那么当你这个服务在N多节点部署时候,session共享又要解决,增加额外的开销。个人项目中使用的是jwt这个技术,简单说就是当你登陆成功后服务器会给你一个令牌,你拿着这个令牌去访问每个接口,服务器会对你的令牌进行鉴权,服务器能够知道你是谁,是否有权限。当在多个节点部署时候,每台服务器都是可以解析的。如果你有更好的解决方案,还请多多指教。下面说下我是怎么做的。本文是在一个springboot的Web项目基础上的。

思路:1.引入jwt的jar包 2.配置一个拦截器 并定义拦截路径 3.注册这个拦截器

注意:在拦截器里面拦截到请求后,进行令牌鉴权。比如查看用户角色,用户登陆时间,令牌是否过期等。在决定是否放行。

第一步:在springboot的web项目基础上添加jwt的jar包

io.jsonwebtoken

jjwt

0.6.0

第二步:配置一个拦截器,并定义拦截路径和规则,注意:secretkey是加解密的密钥、实际使用中替换成你自己的。

完整代码如下:

public class Filterdemo implements Filter {

private static Set<String> path = new HashSet<String>();

// 不拦截的路径

static {

path.add("/");

path.add("/favicon.ico");

path.add("/open");

path.add("/getcode");

path.add("/error");

}

@Override

public void init(FilterConfig filterConfig) throws ServletException {

System.out.println("1.自定义过滤器初始化------");

}

@Override

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

HttpServletRequest request

= (HttpServletRequest) servletRequest;

HttpServletResponse response = (HttpServletResponse) servletResponse;

String url = request.getRequestURI();

System.out.println("过滤器启动,---请求地址:" + url);

// 获取header

final String authHeader = request.getHeader("authorization");

//检查请求接口路径是否在允许的set内

if (path.contains(url)) {

filterChain.doFilter(request, response);

} else {

// 检查 authorization,并检查是否以 "Bearer "开头,注意有一个空格

if (authHeader == null || !authHeader.startsWith("Bearer ")) {

throw new ServletException("认证信息为空或者认证信息不正确");

}

// 截取字符串,截取token

final String token = authHeader.substring(7);

try {

// 解密token

final Claims claims = Jwts.parser().setSigningKey("secretkey").parseClaimsJws(token).getBody();

//把token放request,此处应根据自己实际业务进行

request.setAttribute("claims", claims);

} catch (final SignatureException e) {

throw new ServletException("Invalid token");

}

filterChain.doFilter(servletRequest, servletResponse);

}

}

@Override

public void destroy() {

System.out.println("自定义过滤器销毁");

}

这里是拦截到请求的处理,实际上在用户登陆后就应该给用户颁发令牌,代码如下:

@RequestMapping("/login")

@ResponseBody

public String login(String userName, String passwd) {

//此处仅判断不为空就认为是合法用户,登陆成功

if (userName != null && passwd != null) {

// 生成jwt token返回给前台

String jwtToken = Jwts.builder()

//该JWT所面向的用户,是否使用是可选的;

.setSubject(userName)

//自己希望存储的数据,比如角色,可以放多个

.claim("roles", "member")

.claim("menu", "xxx")

//颁发时间

.setIssuedAt(new Date())

//加密算法和秘钥

.signWith(SignatureAlgorithm.HS256, "secretkey").compact();

return jwtToken;

} else {

System.out.println("用户名或密码为空");

}

return "hello";

}

第三步:注册这个拦截器,注册到系统里

@Configuration

public class filterConfig {

@Bean

public FilterRegistrationBean filterRegistrationBean() {

FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();

//设定我们写的拦截器对象

filterRegistrationBean.setFilter(new Filterdemo());

//设定拦截路径

filterRegistrationBean.addUrlPatterns("/**");

//设置启动顺序,多个拦截器时候使用

filterRegistrationBean.setOrder(2);

return filterRegistrationBean;

}

}


分享到:


相關文章: