(四)、过滤器处理
在过滤器当中需要添加一些不需要进行token校验的请求路径,可以直接访问。 在这里没有角色权限的校验,有需要的可以自行设计。
Java code?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package ichano.developer.sys.filter;`/**`
import ichano.developer.biz.service.ZyLoginService;
import ichano.developer.dto.ZyUserDto;
import ichano.developer.util.KeyUtil;
import ichano.developer.util.TokenUtil;
import java.io.IOException;
import java.security.Key;
import javax.annotation.Priority;
import javax.inject.Inject;
import javax.servlet.ServletContext;
import javax.ws.rs.Priorities;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.PreMatching;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.ext.Provider;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.glassfish.jersey.server.ContainerRequest;
import org.springframework.beans.factory.annotation.Autowired;
/**
* @ClassName: JWTSecurityFilter
* @Description: TODO(权限验证过滤器)
* @author lizhijun
* @date 2016年8月11日 下午1:18:52
*
*/
@Provider
@Priority`(Priorities.AUTHENTICATION)`//优先级最高
//实现该拦截器借口
//@Provider可以自动注册
@PreMatching //这个必须添加,否则无法拦截请求
public class JWTSecurityFilter `implements ContainerRequestFilter{`
final static Logger logger = LogManager.getLogger(JWTSecurityFilter.`class`.getName());
@Autowired
ZyLoginService zyLoginService;
@Context
ServletContext context;
@Inject
javax.inject.Provider<UriInfo> uriInfo;
public static String extractJwtTokenFromAuthorizationHeader(String auth) {
//Replacing "Bearer Token" to "Token" directly
return auth.replaceFirst(`"B|bA|aE|e ", "").replace(" ", ""`);
}
//重写验证过滤器
@Override
public void filter(ContainerRequestContext containerRequestContext) `throws IOException {`
//获取本地的私钥
Key key= KeyUtil.getKey(context);
//得到访问的方法 例如GET,POST
String method = containerRequestContext.getMethod().toLowerCase();
//预校验请求处理
if`(method.equals("options")){`
containerRequestContext.setSecurityContext(`new SecurityContextAuthorizer(uriInfo,new` `AuthorPricinple("pass"), new String[]{"pass"}));`
return`;`
}
//得到访问路径
String path = ((ContainerRequest) containerRequestContext).getPath(`true`).toLowerCase();
System.err.println(`"authorizationHeader path is :"`+path);
//不需要验证,post验证过滤,注册过滤。
if (`"post".equals(method) && "developer/loginuser"`.equals(path)
|| `"developer/registeruser"`.equals(path)
|| `"developer/sendverifcode"`.equals(path)
|| `"developer/updatepwd"`.equals(path)
||`"license/uploadfilecheck"`.equals(path)
||`"product/uploadproductimg"`.equals(path)) {
containerRequestContext.setSecurityContext(`new SecurityContextAuthorizer(uriInfo,new` `AuthorPricinple("pass"), new String[]{"pass"}));`
return`;`
}
//获取头信息中的token
MultivaluedMap<String, String> testToken = ((ContainerRequest) containerRequestContext).getHeaders();
String authorizationHeader = ((ContainerRequest) containerRequestContext).getHeaderString(`"auth_token"`);
//如果token为空抛出
if (authorizationHeader == `null`) {
throw new WebApplicationException(Response.Status.UNAUTHORIZED);`//抛出未认证的错误`
}
//把Bear Token换成Token
String strToken=extractJwtTokenFromAuthorizationHeader(authorizationHeader);
if (TokenUtil.isValid(strToken,key)){
String name=TokenUtil.getName(strToken,key);`//反解出Name`
// String[] roles=TokenUtil.getRoles(strToken,key);//反解出角色
if`(name !=null){`
ZyUserDto user=zyLoginService.findUserByName(name);
if`(user!=null){`
containerRequestContext.setSecurityContext(`new SecurityContextAuthorizer(uriInfo,new` `AuthorPricinple(name), new String[]{"user"}));`
return`;`
}
else`{`
logger.info(`"User not found " + name);`
}
}
else {
logger.info(`"name, roles or version missing from token"`);
}
}
else {
logger.info(`"token is invalid"`);
}
throw new WebApplicationException(Response.Status.UNAUTHORIZED);
}
}
(五)、前端请求代码:
采用ajax post请求方式。
// 发送登陆请求
JavaScript code?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$.ajax({
url: `"http://192.168.0.55:8080/developer/developer/loginUser"`,
type: `"POST"`,
dataType: `"json"`,
contentType: `"application/json", <span style="color: #FF0000;"> //注意:如果有post data参数的时候,必须加这段,否则请求获取不到参数</span> `
data: {
user_name: userName,
password: userPwd,
type: type
},
success: `function`(data) {
console.log(data);
if (data.code == 1000) {
$.cookie(`'token'`, data.data.token);
console.log(1);
parent.location.reload();
} `else if (data.code == 2006) {`
layer.msg(`"用户名密码错误"`);
} `else {`
layer.msg(`"登陆异常"`);
}
}
});
//访问接口请求
JavaScript code?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$.ajax({
url: `"http://192.168.0.181:9102/developer/developer/checkLogin"`,
type: `'POST'`,
dataType: `'json'`,
beforeSend: `function(request) { //添加请求响应头中的自定义token`
request.setRequestHeader(`"auth_token"`, token);
},
success: `function`(data) {
if (data.code == 1000) {
var html = [];
html.push(Mustache.render(userNameTemp, data.data));
$userNameCon.html(html.join(`''`));
} `else {`
window.location.href = `"index.html"`
}
}
})
二、CORS跨域访问
使用cors进行跨域配置其实很简单,只需要引用jar包,然后添加过滤器即可。但是有些细节还是要注意。
(一)、jar包引用
<dependency>
<groupId>com.thetransactioncompany</groupId>
<artifactId>cors-filter</artifactId>
<version>2.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.thetransactioncompany/java-property-utils -->
<dependency>
<groupId>com.thetransactioncompany</groupId>
<artifactId>java-property-utils</artifactId>
<version>1.9.1</version>
</dependency>
(二)、过滤器实现
web.xml配置:
Java code?
1
2
3
4
5
6
7
8
<filter>
<filter-name>cros</filter-name>
<filter-`class>ichano.developer.sys.filter.CorsFilter</filter-class`>
</filter>
<filter-mapping>
<filter-name>cros</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
过滤器中可以配置允许访问的请求方,允许访问的请求方式以及允许通过的请求头信息
Java code?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package ichano.developer.sys.filter;`/**`
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.filter.OncePerRequestFilter;
/**
* @ClassName: CorsFilter
* @Description: TODO(设置其他IP地址的机器可以直接访问本项目Url--工具filter)
* @author lizhijun
* @date 2016年8月15日 下午2:25:25
*
*/
public class CorsFilter `extends OncePerRequestFilter {`
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) `throws ServletException, IOException {`
response.addHeader(`"Access-Control-Allow-Origin", ""); //为安全起见,可配置允许访问的请求方地址。这里配置成号,是允许所有访问。`
response.addHeader(`"Access-Control-Allow-Methods", "GET, POST, PUT, DELETE"); //为安全起见,也可配置成只允许POST请求`
response.addHeader(`"Access-Control-Allow-Headers", "Content-Type,auth_token"); //这里要注意,auth_token是我自定义的请求头当中带的token,在这里必须添加,否则你永远获取不到。`
response.addHeader(`"Access-Control-Max-Age", "1800");//30 min`
filterChain.doFilter(request, response);
}
}
这里处理了三个坑,
**一是在本地调试的时候可以跨域访问,但是部署到服务器之后,访问失败。解决方法:请求地址后面加上端口号就可以访问。 这个问题就需要在nignx里面进行端口配置。
二是CROS这种传输方式传输的数据到后端接收已不是JSON格式,而是类似于XXX=123&FFFF=384这样的格式,需要对所有请求的入参进行一下转换成json格式。
三是请求头中的自定义字段auth_token在服务器上接收不到,这里需要对ngnix进行配置,允许自定义属性的header配置。
[b]**
Original url: Access
Created at: 2020-09-02 17:59:02
Category: default
Tags: none
未标明原创文章均为采集,版权归作者所有,转载无需和我联系,请注明原出处,南摩阿彌陀佛,知识,不只知道,要得到
最新评论