java 单机接口限流处理方案
377
2022-10-05
Springboot 如何实现filter拦截token验证和跨域
Springboot filter拦截token验证和跨域
背景
web验证授权合法的一般分为下面几种
使用session作为验证合法用户访问的验证方式
使用自己实现的token
使用OCA标准
在使用API接口授权验证时,token是自定义的方式实现起来不需要引入其他东西,关键是简单实用。
合法登陆后一般使用用户UID+盐值+时间戳使用多层对称加密生成token并放入分布式缓存中设置固定的过期时间长(和session的方式有些相同),这样当用户访问时使用token可以解密获取它的UID并据此验证其是否是合法的用户。
#springboot中实现filter
一种是注解filter
一种是显示的硬编码注册filter
先有filter
import javax.servlet.annotation.WebFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import springfox.documentation.spring.web.json.Json;
import com.alibaba.fastjson.JSON;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/***************
* token验证拦截
* @author bamboo zjcjava@163.com
* @time 2017-08-01
*/
@Component
//@WebFilter(urlPatterns = { "/api/v/*" }, filterName = "tokenAuthorFilter")
public class TokenAuthorFilter implements Filter {
private static Logger logger = LoggerFactory
.getLogger(TokenAuthorFilter.class);
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse rep = (HttpServletResponse) response;
//设置允许跨域的配置
// 这里填写你允许进行跨域的主机ip(正式上线时可以动态配置具体允许的域名和IP)
rep.setHeader("Access-Control-Allow-Origin", "*");
// 允许的访问方法
rep.setHeader("Access-Control-Allow-Methods","POST, GET, PUT, OPTIONS, DELETE, PATCH");
// Access-Control-Max-Age 用于 CORS 相关配置的缓存
rep.setHeader("Access-Control-Max-Age", "3600");
rep.setHeader("Access-Control-Allow-Headers","token,Origin, X-Requested-With, Content-Type, Accept");
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
String token = req.getHeader("token");//header方式
ResultInfo resultInfo = new ResultInfo();
boolean isFilter = false;
String method = ((HttpServletRequest) request).getMethod();
if (method.equals("OPTIONS")) {
rep.setStatus(HttpServletResponse.SC_OK);
}else{
if (null == token || token.isEmpty()) {
resultInfo.setCode(Constant.UN_AUTHORIZED);
resultInfo.setMsg("用户授权认证没有通过!客户端请求参数中无token信息");
} else {
if (TokenUtil.volidateToken(token)) {
resultInfo.setCode(Constant.SUCCESS);
resultInfo.setMsg("用户授权认证通过!");
isFilter = true;
} else {
resultInfo.setCode(Constant.UN_AUTHORIZED);
resultInfo.setMsg("用户授权认证没有通过!客户端请求参数token信息无效");
}
}
if (resultInfo.getCode() == Constant.UN_AUTHORIZED) {// 验证失败
PrintWriter writer = null;
OutputStreamWriter osw = null;
try {
osw = new OutputStreamWriter(response.getOutputStream(),
"UTF-8");
writer = new PrintWriter(osw, true);
String jsonStr = JSON.toJSONString(resultInfo);
writer.write(jsonStr);
writer.flush();
writer.close();
osw.close();
} catch (UnsupportedEncodingException e) {
logger.error("过滤器返回信息失败:" + e.getMessage(), e);
} catch (IOException e) {
logger.error("过滤器返回信息失败:" + e.getMessage(), e);
} finally {
if (null != writer) {
writer.close();
}
if (null != osw) {
osw.close();
}
}
return;
}
if (isFilter) {
logger.info("token filter过滤ok!");
chain.doFilter(request, response);
}
}
}
@Override
public void init(FilterConfig arg0) throws ServletException {
}
}
注解配置filter
加上如下配置则启动时会根据注解加载此filter
@WebFilter(urlPatterns = { “/api/*” }, filterName = “tokenAuthorFilter”)
硬编码注册filter
在application.java中加入如下代码
//注册filter
@Bean
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
TokenAuthorFilter tokenAuthorFilter = new TokenAuthorFilter();
registrationBean.setFilter(tokenAuthorFilter);
List
urlPatterns.add("/api/*");
registrationBean.setUrlPatterns(urlPatterns);
return registrationBean;
}
以上两种方式都可以实现filter
跨域说明
springboot可以设置全局跨域,但是对于filter中的拦截地址并不其中作用,因此需要在dofilter中再次设置一次
区局设置跨域方式如下
方式1.在application.java中加入如下代码
//跨域设置
private CorsConfiguration buildConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
return corsConfiguration;
}
/**
* 跨域过滤器
* @return
*/
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", buildConfig()); // 4
return new CorsFilter(source);
}
方式2.配置注解
必须集成WebMvcConfigurerAdapter类
/**********
* 跨域 CORS:使用 方法3
* 方法:
1服务端设置Respone Header头中Access-Control-Allow-Origin
2配合前台使用jsonp
3继承WebMvcConfigurerAdapter 添加配置类
http://blog.csdn.net/hanghangde/article/details/53946366
* @author xialeme
*
*/
@Configuration
public class CorsConfig extends WebMvcConfigurerAdapter{
/* @Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowCredentials(true)
.allowedMethods("GET", "POST", "DELETE", "PUT")
.maxAge(3600);
} */
private CorsConfiguration buildConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*"); // 1
corsConfiguration.addAllowedHeader("*"); // 2
corsConfiguration.addAllowedMethod("*"); // 3
return corsConfiguration;
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", buildConfig()); // 4
return new CorsFilter(source);
}
}
springboot配置Filter & 允许跨域请求
1.filter类
加注解:
@WebFilter(filterName = "authFilter", urlPatterns = "/*")
代码如下:
package com.activiti.filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
// renwenqiang
@WebFilter(filterName = "authFilter", urlPatterns = "/*")
public class SystemFilter implements Filter {
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException,
ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
response.setHeader("Access-Control-Allow-Origin","*");
System.out.println(request.getRequestURL());
filterChain.doFilter(request, servletResponse);
}
@Override
public void destroy() {
}
@Override
public void init(FilterConfig arg0) throws ServletException {
}
}
2.启动类
加注解:
@ServletComponentScan(basePackages = {"com.activiti.filter"})
代码如下:
package com;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.orm.jpa.vendor.HibernateJpaSessionFactoryBean;
import org.springframework.scheduling.annotationhttp://.EnableScheduling;
@SpringBootApplication(exclude = {
org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration.class,
org.activiti.spring.boot.SecurityAutoConfiguration.class })
@ServletComponentScan(basePackages = {"com.activiti.filter"})
public class DemoActiviti0108Application {
@Bean
public HibernateJpaSessionFactoryBean sessionFactory() {
return new HibernateJpaSessionFactoryBean();
}
public static void main(String[] args) {
SpringApplication.run(DemoActiviti0108Application.class, args);
}
}
3.jquery ajax请求代码实例:
new Vue({
el: '#app',
data: {
models: []
},
created: function () {
$.ajax({
type: 'GET',
url: 'http://localhost:8081/activiti/model/all',
beforeSend: function() {
console.log('beforeSend');
},
data:{},
dataType: "json",
xhrFields: {
withCredentials: false
},
crossDomain: true,
async: true,
//jsonpCallback: "jsonpCallback",//服务端用于接收callback调用的function名的参数
}).done((data) => {
console.log('donehttp://');
console.log(data);
this.models = data;
}).fail((error) => {
console.log('fail');
console.log('error');
});
}
})
大功告成 回家睡觉 嘻嘻嘻~
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~