应用场景,在方法级别对本次调用进行鉴权,如api接口中有个用户唯一标示accessToken,对于有accessToken的每次请求可以在方法加一个拦截器,获得本次请求的用户,存放到request或者session域。
python中,之前在python flask中可以使用装饰器来对方法进行预处理,进行权限处理
先看一个实例,使用@access_required拦截:
1
2
3
4
5
6
7
8
|
@api
.route(
'/post_apply'
)
@access_required
def
apply
():
"""
活动报名
"""
print
'报名者是:'
+
g.user
return
jsonify(response_data)
|
实现很简单:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
# 验证access_token并保存当前用户到g中
def
access_required(f):
@wraps(f)
def
decorated_func(
*
args,
*
*
kwargs):
access_token
=
request.values.get(
'access_token'
)
if
access_token
=
=
None
:
return
error_msg(
'500'
,
'access_token required'
)
if
access_token
=
=
"":
return
error_msg(
'500'
,
'access_token can not empty'
)
if
is_access_token(access_token)
=
=
False
:
return
error_msg(
'500'
,
'invalid_access_token'
)
return
f(
*
args,
*
*
kwargs)
return
decorated_func
|
java中,自定义注解拦截器来实现,在需要的拦截的方法上面加上一个注解@AccessRequired
spring mvc Controller中的使用实例
1
2
3
4
5
6
7
8
9
|
/**
* 注解拦截器方法
* @return
*/
@RequestMapping
(value=
"/urlinter"
,method=RequestMethod.GET)
@AccessRequired
public
@ResponseBody
String urlInterceptorTest() {
return
"通过拦截器:user"
+request.getAttribute(
"currUser"
);
}
|
如何实现以上实例呢?
定义一个注解:
1
2
3
4
5
6
7
8
9
10
|
import
java.lang.annotation.ElementType;
import
java.lang.annotation.RetentionPolicy;
import
java.lang.annotation.Target;
import
java.lang.annotation.Retention;
@Target
(ElementType.METHOD)
@Retention
(RetentionPolicy.RUNTIME)
public
@interface
AccessRequired {
}
|
搞一个拦截器:
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
|
/**
* 拦截url中的access_token
* @author Nob
*
*/
public
class
UserAccessApiInterceptor
extends
HandlerInterceptorAdapter {
public
boolean
preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler)
throws
Exception {
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
AccessRequired annotation = method.getAnnotation(AccessRequired.
class
);
if
(annotation !=
null
) {
System.out.println(
"你遇到了:@AccessRequired"
);
String accessToken = request.getParameter(
"access_token"
);
/**
* Do something
*/
response.getWriter().write(
"没有通过拦截,accessToken的值为:"
+ accessToken);
}
// 没有注解通过拦截
return
true
;
}
}
|
在spring mvc配置文件中:
1
2
3
4
5
6
7
8
9
10
11
12
|
<!-- 拦截器 -->
<
mvc:interceptors
>
<
mvc:interceptor
>
<!-- 对所有的请求拦截使用/** ,对某个模块下的请求拦截使用:/myPath/* -->
<
mvc:mapping
path
=
"/**"
/>
<
ref
bean
=
"userAccessInterceptor"
/>
</
mvc:interceptor
>
</
mvc:interceptors
>
<
bean
id
=
"userAccessInterceptor"
class
=
"com.banmacoffee.web.interceptor.UserAccessApiInterceptor"
>
</
bean
>
|
大功告成,你可以在拦截器里为所欲为,并且把它加载任何你想的Controller 请求的方法上。
http://www.open-open.com/lib/view/open1408004883004.html