关于spring-security 表单登录参数为null问题
写在前面
由于第一次使用SpringSecurity做登录认证模块,在此期间遇到不少的问题,在此记录下自己遇到的坑。
前端使用了axios进行数据的交互,代码如下:
postRequest('/login', {
username: username,
password: password
}).then(resp=> {
_this.loading = false;
if (resp.status == 200) {
//成功
} else {
//失败
}
}, resp=> {
//失败
});
postRequest函数内容如下:
export const postRequest = (url, params) => {
return axios({
method: 'post',
url: `${url}`,
data: params,
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
}
})
}
服务端登录配置如下:
protected void configure(HttpSecurity http) throws Exception {
....
http.loginProcessingUrl("/login")
.usernameParameter("username")
.passwordParameter("password");
....
}
服务端认证代码如下:
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
User user= userService.loadUserByUsername(s);
if(user==null){
return new User();
}
List<Role> roles = rolesService.getRoleByUid(user.getId());
user.setRoles(roles);
return user;
}
前端进行登录请求的时候一直提示登录失败,查看服务端后台log如下:
根据log,查看了服务端代码,发现UserDetailsService接口中的loadUserByUsername接收到的字符串为null。所以返回了一个空的User对象,导致密码匹配认证不通过。所以登录失败了。
于是我使用了API调试工具进行登录测试:
发现可以登录成功,于是猜测可能是前端的交互方式有问题,于是Google了一下,发现SpringSecurity默认的登录数据是通过 key/value 的形式来传递的,默认情况下不支持 JSON格式的登录数据。 知道原因之后就好解决了,可以将axios中的参数改为key/value的方式:
postRequest('/login','username='+username+'&password='+password).then(resp=>{
if(resp.status==200){
//成功
this.$alert('登录成功!','成功!');
}else{
this.$alert('登录失败!','失败!');
}
},resp=>{
_this.$alert('找不到服务器!', '失败!');
})
或者使用qs库将Json对象以 k=v的格式进行格式化
export const postRequest = (url, params) => {
return axios({
method: 'post',
url: `${base}${url}`,
data: qs.stringify(params),
})
}
这样就可以成功登录,问题解决。