前后端分离实现登录拦截
程序员文章站
2022-03-15 11:42:17
...
一.认证方案
1.Session
利用Session我们可以管理用户状态:
- 服务器接受第一个请求时候,生成session对象,并通过响应头告诉客户端在cookie中放入sessionId
- 客户端之后发送请求时,会带上包含sessionId的cookie
- 服务器通过sessionId获取session,进而得到当前的状态
- 每次客户端访问服务端带上sessionId即可
2.客户端存储方案
特性 | cookie | localStorage | sessionStorage |
---|---|---|---|
生命周期 | 一般由服务器生成,可设置失效时间。如果在浏览器端生成cookie,默认是关闭浏览器后失效 | 除非被清除,否则永久保存 | 仅在当前会话下有效,关闭页面或浏览器后被清除 |
数据大小 | 4K左右 | 一般为5MB | 一般为5MB |
通信方式 | 每次都会携带在HTTP头中,如果使用cookie保存过多数据会带来性能问题 | 仅在客户端(即浏览器)中保存,不参与和服务器的通信 | 同 localStorage |
二.为什么需要前后端拦截
之前前端拦截的思路是:
- 判断的路径是否需要登录;如果需要,判断store里面有没有存储user信息
- store有放行,没有就要跳到登录页面
这样是不安全的,我们可以在控制台输入
window.localStorage.setItem('user', JSON.stringify({"name":"哈哈哈"}));
从而去伪造,访问任何一个页面了。
所以
要实现靠谱的拦截,由后端验证用户登录状态,前端带上sessionId发送请求交由后端认证。
三.前后端拦截
3.1后端拦截
默认情况下,跨域的cookie是被禁止的,需要两边都要设置。跨域情况下会先发出一个options请求试探,这个请求是不带cookie信息的,所以shiro无法获取到sessionId
public class LoginInterceptor implements HandlerInterceptor{
@Override
public boolean preHandle (HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
// 放行 options 请求,否则无法让前端带上自定义的 header 信息,导致 sessionID 改变,shiro 验证失败
if (HttpMethod.OPTIONS.toString().equals(httpServletRequest.getMethod())) {
httpServletResponse.setStatus(HttpStatus.NO_CONTENT.value());
return true;
}
Subject subject = SecurityUtils.getSubject();
// 使用 shiro 验证
if (!subject.isAuthenticated()) {
return false;
}
return true;
}
}
这里记录一下,我把这段代码屏蔽,也可以用。现在暂时不知道是什么原因。
SpringMVC配置允许跨域
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowCredentials(true)
.allowedOrigins("http://localhost:8080")
.allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE")
.allowedHeaders("*")
}
3.2前端拦截
在main.js加上
axios.defaults.withCredentials = true
为了防止伪造参数,绕过前端路由限制,在每个页面钱都向后端发送一个请求,目的是经由拦截器验证服务端的登录状态,防止上述情况的发生。
router.beforeEach((to, from, next) => {
if (to.meta.requireAuth) {
if (store.state.user) {
axios.get('/authentication').then(resp => {
if (resp.data) next()
})
} else {
next({
path: 'login',
query: {redirect: to.fullPath}
})
}
} else {
next()
}
}
)
三.感谢
学习参考https://learner.blog.csdn.net/article/details/102788866