【发布时间】:2020-11-10 00:47:28
【问题描述】:
我将会话存储在数据库中,我有包含用户 ID、UUID 和到期日期的列。在来自 Angular 的任何请求之前,我想向 api 中的方法发送请求,该方法检查到期日期并让 angular 发送另一个请求(如果有效或注销用户)并删除带有令牌的本地存储以及关于我的会话到期日期的消息。我正在寻找与 HTTPInterceptor 类似的解决方案,它会自动将标头添加到每个请求中,而不是将标头添加到之前有请求的任何方法中。
我正在使用 Angular 10 和 Spring Boot 2.3.1。
编辑。
我找到了在 Angular 端的拦截器中捕获任何请求中的错误的解决方案。
@Injectable()
export class HttpInterceptorService implements HttpInterceptor {
constructor() {}
intercept(req: HttpRequest<any>, next: HttpHandler) {
if (localStorage.getItem('username') && localStorage.getItem('basicauth')) {
req = req.clone({
setHeaders: {
Authorization: localStorage.getItem('basicauth')
}
})
}
return next.handle(req).pipe(
catchError(response => {
console.log(response.status)
// do something, example clear LocalStorage...
return throwError(response);
})
)
}
}
编辑 2。
我在 Spring-Boot 中使用 preHandle() 方法制作了拦截器,以在请求之前检查会话过期日期,如果会话过期,我将唯一响应状态设置为 495,它告诉 Angular 注销用户并清除 LocalStorage。
Spring-Boot 中的 preHandle() 方法:
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//if (request.getRequestURL().toString().endsWith("/api/basicauth"))
String GUID = request.getHeader("GUID") == null? "1" : request.getHeader("GUID");
if (sessionService.getSessionByGuid(GUID).isPresent()) {
Session session = sessionService.getSessionByGuid(GUID).get();
if(session.getExpirationDate().isBefore(LocalDateTime.now())) {
sessionService.deleteSession(GUID);
response.setStatus(495);
return false;
} else {
sessionService.renewSession(session);
return true;
}
}
return true;
}
Angular 中的拦截器方法:
intercept(req: HttpRequest<any>, next: HttpHandler) {
if (localStorage.getItem('username') && localStorage.getItem('basicauth')) {
req = req.clone({
setHeaders: {
Authorization: localStorage.getItem('basicauth'),
GUID: localStorage.getItem('GUID')
}
})
}
return next.handle(req).pipe(
catchError(response => {
if (response.status == 495) {
this.auth.removeSessionAndStorage();
this.openSnackBar("Twoja sesja wygasłą!",);
this.router.navigate(['login', 'session-expired']);
}
return throwError(response);
})
);
}
【问题讨论】:
-
这太低效了。只需发送您的请求,检查令牌,如果令牌过期并在此时重新验证,则响应 401。为自己节省往返服务器的时间。
-
@bryan60 并在错误部分清除我在
subcribe中的本地存储内容? -
可能会想在你的拦截器中使用
catchError运算符,然后检查状态码以了解要做什么。 -
@bryan60 你能看看我在 Angular 方面的解决方案吗?我编辑了帖子。
-
这是我曾经做过的关于身份验证拦截器的回答:stackoverflow.com/questions/46017245/…
标签: java angular spring-boot request interceptor