工作室项目里面需要实现登录校验,因为打算做的app,现在没学安卓,暂时用的vue做了个H5版的,所以用的是token进行登录校验,没有使用传统的cookie session
时间:2021-1-20
一、技术要点
前端:
1.Axios及拦截器
2.vue路由
后端:
1.token的使用(用的是jwt)
2.servlet及过滤器
二、流程
- 前端登录发送axios请求,
- 后端接收数据后核验,如果正确返回生成的token和用户的基本信息,否则返回401
- 前端接收token后存储在localstorage中,在之后的每一次请求中给请求头添加token
- 后端使用过滤器,对每一个请求检查token,正确则放行,不存在或错误则返回401
三、具体代码
1.axios发送登录请求
login.vue
前端登录代码
this.$qs.stringify(data) 将参数序列化成URL的形式,从而可以发送formData类型的数据
axios默认以play load的类型发送参数,
export default {
data(){
return {
user:{
userPhone:"",
userPassward:""
}
}
},
methods:{
login:function(){
let data = {P
userPhone:this.user.userPhone,
userPassword:this.user.userPassward
};
this.$axios.post('http://localhost/login',this.$qs.stringify(data))
.then((res)=>{
if(res.status == 200){
//将token和用户的基本信息存储在localStorage
localStorage.setItem("user",JSON.stringify(res.data));
localStorage.setItem("authorization",res.headers.authorization);
//跳转首页
this.$router.push('/index');
}
})
.catch((err)=>{
alert("账号或密码错误!");
console.log(err);
})
}
}
}
2.使用拦截器对每一个请求的请求头加上token
main.js
在main.js中配置axios拦截器,给每个请求的请求头加上token
不懂的可以搜axios拦截器
import axios from 'axios'
Vue.prototype.$axios = axios
axios.interceptors.request.use(
config=>{
const authorization = localStorage.getItem('authorization')
console.log('axios拦截器拦截请求');
if (authorization) {
config.headers.authorization = authorization
}
return config
},
err =>{
console.log('err:'+err);
return Promise.reject(err)
}
)
3. 在前端校验是否登录
index.js
在router的index.js中给每一个路由配置beforeEach,在每一个路由跳转前判断是否登录,未登录返回登录界面,
关于此知识点可以搜索vue路由钩子函数
const router = new Router({
routes:[
......
]
})
router.beforeEach(
(to,from,next)=>{
let authorization = localStorage.getItem('authorization');
if(authorization){//是否存在token
if(to.name == 'login'){
console.log("已登录,跳转首页!");
next('/index')
}else {
next();
}
}else {
if(to.name == 'login'){
next();
}else {
console.log("未登录,跳转登录页!");
next('/');
}
}
}
)
export default router
4.后端登录请求
LoginServlet.java
变量下划线就不要管了,不规范,数据库用的下划线,工具栏生成的忘记改了,注意一下
Gson转成json输出时是字符串,等axios接收后不知道为什么是对象了,所以前端用JSON.stringify又转了一遍.,按道理response.getWriter().write()不会自动将json字符串转成对象,print()会,之前用Ajax可以返回字符串,希望知道的大佬告知一声,谢谢!
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//从前端表单获取的账号密码
String user_phone = request.getParameter("user_phone");
String user_password = request.getParameter("user_password");
System.out.println("手机号:"+user_phone+"密码:"+user_password);
//调用业务层代码进行登录
UserService userService = new UserServiceImpl();
User user = userService.login(user_phone,user_password);
if(user==null){
response.setStatus(401);
}else {//向前端回传
String token = TokenUtils.token(user.getUser_phone());
User localUser = new User(user.getUser_id(),user.getUser_name(),user.getUser_phone(),user.getUser_realname(),user.getUser_school());
Gson gson = new Gson();
String json = gson.toJson(localUser);
response.setHeader("Authorization",token);
System.out.println("用户:"+json);
response.getWriter().write(json);
}
}
6.后端过滤器,对前端每一个请求进行过滤
LoginFilter.java
过滤器,对前端传来的请求过滤,
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
HttpServletRequest request=(HttpServletRequest) req;
HttpServletResponse response=(HttpServletResponse) resp;
//获取请求资源路径
String requestURI = request.getRequestURI();
System.out.println(requestURI);
//3.判断是否包含登录相关资源路径
if ( requestURI.contains("login") ) {
System.out.println("这是登录界面,放行");
chain.doFilter(req, resp);
} else {
//4.判断是否有token
String authorization= request.getHeader("authorization");
if(authorization!=null){
boolean verify = TokenUtils.verify(authorization);
if(verify){
chain.doFilter(req, resp);
System.out.println("token有效,放行");
}else {
response.setStatus(401);
System.out.println("token无效,401");
}
}else {
System.out.println("token不存在,401");
response.setStatus(401);
}
}
}
四、结语
- 不用axios直接用Ajax,我还不知道怎么处理给每个请求头加上token,在网上没有找到合适的方法,难道真的只能复制粘贴给每个请求加上token吗?
- Gson转成json输出时是字符串,等axios接收后不知道为什么是对象了,所以前端用JSON.stringify又转了一遍.,按道理response.getWriter().write()不会自动将json字符串转成对象,print()会,之前用Ajax可以返回字符串,希望知道的大佬告知一声,谢谢!
本人实力有限,如有错误或更好的建议,还望各位不吝赐教