在之前实现的版本中,如果你进行测试,可以看到在浏览器的local Storage中,确实里面有了我们加入的Authorization,而且如果没有登录的话,直接访问主页会进入登录页面。但其实有好几个问题并没有解决:一、我们所加的Authorzation其实并不是从服务器传过来的,而是自己的测试:只要服务器传过来了200的响应状态码,我们就自己加上固定的Authorization二、我们重新进入的时候,判断条件是只要有Authorization就可以直接进入了,但其实应该提交给服务器判断这个Authorization是否在数据库中,才可以。基于以上两点,我们对代码进行修改:
首先就是,我们获取的token应该是从服务器获取的,而不是自己给定,因此直接在服务器上接收到信息后修改:
@RequestMapping(value = "/login",method = RequestMethod.POST)

public RespBean login(

@RequestBody UserLogin userLogin,

Model model

){

if (userService.check(userLogin)){

String token = UUID.randomUUID().toString();
//
System.out.println(token);

userService.autoLog(userLogin,token);

return new RespBean("success","登录成功",token);


}else{

return new RespBean("fail","登录失败");

}

}
@RequestMapping(value = "/login",method = RequestMethod.POST)

public RespBean login(

@RequestBody UserLogin userLogin,

Model model

){

if (userService.check(userLogin)){

String token = UUID.randomUUID().toString();
//
System.out.println(token);

userService.autoLog(userLogin,token);

return new RespBean("success","登录成功",token);


}else{

return new RespBean("fail","登录失败");

}

}这里使用uuid直接生成随机的token,为了用respBean传递回去数据,因此传递回去的对象除了状态信息和消息之外,还需要多加一个token:
RespBean对象代码为:

public class RespBean {

private String status;

private String msg;

private String token = null;
}

public class RespBean {

private String status;

private String msg;

private String token = null;
}各种方法自己加上就好了。
如果仔细的话,会发现我们传进来的参数好像跟上一次的不一样了,上一次传递了两个用@RequestParam修饰的账号密码的String类型的对象,而这一次直接传递了一个UserLogin的对象,这是因为我觉得如果要接收表单等信息的话,每一个都使用这样的一个个参数会显得接收参数很多,而且如果要修改接收的数值的话,可能需要很多地方都要修改,复用性太差了。
第二个原因是我们的Controller层应该只是最大限度的逻辑表示,而具体怎么添加用户、怎么鉴别用户是否登录等信息,完完全全应该交给下层的Service层呀Mapper层呀去做,但如果接收的是这样的password、username等数值的话,调用下一层的时候,我们还需要把这些数值直接放入,否则就要在Controller层对数据进行操作,这就破坏层次结构了。
所以,为了解决这个问题,我们可以把所有表单中需要用到的数据单独封装成一个对象,这个对象就专门用来接收web的数据以及在各个层之间流转:
java @Data public class UserLogin { private String username; private String password; }把,
这里的@Data注解就是lombok的注解,可以让我们不用再去创建get、set等方法了。这样创建完对象以后,我们的登录操作就可以直接将这样的对象拿来使用了。
java @Data public class UserLogin { private String username; private String password; }但是,如果你是跟着做下来的,就会遇到跟我一样的问题:登录的时候会报错:
Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Unrecognized token 'username': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false'); nested exception is com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'username': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false')
Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Unrecognized token 'username': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false'); nested exception is com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'username': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false')大概的意思就是说,我们接受的跟发出的不大一样,对应不上,而这样的原因是:我们当时为了使用get和@RequestParam方法,在api.js中,把获取到的json数据格式,变成了json字符串的格式了,所以就不能使用@RequestBody这样一个接收json对象的方法来接收了。
因此上一个程序中的api.js改为:
export const postRequest = (url, params) => {
return axios({

method: 'post',

url: `${base}${url}`,

data: params,


// transformRequest: [function (data) {

//
// Do whatever you want to transform the data

//
let ret = ''

//
for (let it in data) {

//
ret += encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&'

//
}

//
return ret

// }],

headers: {

'Content-Type': 'application/json;charset=UTF-8'

}
});
}
export const postRequest = (url, params) => {
return axios({

method: 'post',

url: `${base}${url}`,

data: params,


// transformRequest: [function (data) {

//
// Do whatever you want to transform the data

//
let ret = ''

//
for (let it in data) {

//
ret += encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&'

//
}

//
return ret

// }],

headers: {

'Content-Type': 'application/json;charset=UTF-8'

}
});
}详细的可以看一下这个文章@RequestBody和@RequestParam的区别而第二点,关于如何实现鉴别token,就是在路由之前的那个方法上,加上传递给服务器以及接收相应信息进行操作:
router.beforeEach((to,from,next)=>{
if(to.path ==='/login'){

next();
}else {

let token = localStorage.getItem('Authorization');


if(token ===null || token ===''){

next('/login');

}else {

getRequest('/autoLog',{

token:token

}).then(resp=>{

if(resp.status == 200){

var json = resp.data;

if(json.status=='success'){

next();

}else{

// next('/login');

}

}else{

alert('请求失败', '失败!');

}

})

}
}
});
router.beforeEach((to,from,next)=>{
if(to.path ==='/login'){

next();
}else {

let token = localStorage.getItem('Authorization');


if(token ===null || token ===''){

next('/login');

}else {

getRequest('/autoLog',{

token:token

}).then(resp=>{

if(resp.status == 200){

var json = resp.data;

if(json.status=='success'){

next();

}else{

// next('/login');

}

}else{

alert('请求失败', '失败!');

}

})

}
}
});服务器的处理也就很简单了,跟上面登录其实是差不多的,就不再列举出来了以上就是Vue+Vuex实现自动登录的知识点详解的详细内容,关于Vue+Vuex实现自动登录的资料请关注其它相关文章!