前言
众所周知,spring-security默认是form表单模式登录的,故我们只要在前端用表单提交即可,回顾我上次umi前端请求处理,代码如下
1/**
2 * 成功登录获得token
3 * @param {*} params
4 */
5export async function fakeAccountLogin(params) {
6 return request('/login', {
7 method: 'POST',
8 data: params,
9 requestType: 'form' // 后端请求token需要表单的形式
10 });
11}
很明显,request使用了requestType这个属性,决定了表单形式。所以能直接进入spring-security的默认方法了进行认证。
针对使用json模式
在这里我们只要稍微处理一下就可以
- 处理SpringConfig
原来:
1 @Override
2 protected void configure(HttpSecurity http) throws Exception {
3 http
4 // 让跨域配置被使用
5 .formLogin().successHandler(myAuthenticationSuccessHandler)
6 .failureHandler(myAuthenticationFailHandler)
7 .and()
8 .cors()
9 .and()
10 .csrf().disable()
11 // 添加异常处理
12 .exceptionHandling()
13 .authenticationEntryPoint(tokenExceptionHandler)
14 .accessDeniedHandler(accessDeniedException)
15 .and()
16 //关闭session
17 .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
18 .and()
19
20 // 拦截所有请求
21 .authorizeRequests()
22 .antMatchers(HttpMethod.POST,"/api/login").permitAll()
23 .antMatchers("/api/**").authenticated();
24
25 // 替换过滤器
26 http.addFilterAt(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
27
28}
改变后:
1 http
2
3 .cors()
4 .and()
5 .csrf().disable()
6 // 添加异常处理
7 .exceptionHandling()
8 .authenticationEntryPoint(tokenExceptionHandler)
9 .accessDeniedHandler(accessDeniedException)
10 .and()
11 //关闭session
12 .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
13 .and()
14
15 // 拦截所有请求
16 .authorizeRequests()
17 .antMatchers(HttpMethod.POST,"/api/login").permitAll()
18 .antMatchers("/api/**").authenticated();
19
20 // 替换过滤器
21 http.addFilterAt(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
在这里一对比很明显就看到,已经去掉了form的处理形式,包括成功和失败的处理器
1 @Bean(name = "myAuthenticationManager")
2 @Override
3 public AuthenticationManager authenticationManagerBean() throws Exception {
4 return super.authenticationManagerBean();
5 }
还有在config里面增加了认证管理器的bean,这个是最重要的。
- 增加loginController的处理方法
1/**
2 * @Description LoginController
3 * @Author YiLong Wu
4 * @Date 2020/2/28 13:43
5 * @Version 1.0.0
6 */
7@RestController
8@Slf4j
9public class LoginController {
10
11 @Resource(name = "userDao")
12 private UserDao userDao;
13
14 @Resource(name = "myAuthenticationManager")
15 private AuthenticationManager myAuthenticationManager;
16
17
18 @PostMapping("/login")
19 public Response login(@RequestBody UserDto userDto) {
20 log.info("************{}",userDto);
21 User byUsername = userDao.findByUsername(userDto.getUsername());
22
23 if(byUsername == null || !MD5Util.string2MD5(userDto.getPassword()).equals(byUsername.getPassword())) {
24 return new Response(-1,"用户名或密码错误",null);
25 }
26
27 // 进行认证
28 UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(userDto.getUsername(),userDto.getPassword());
29 Authentication authenticate = myAuthenticationManager.authenticate(usernamePasswordAuthenticationToken);
30
31 //从authentication中获取用户信息
32 JwtUser userDetail= (JwtUser)authenticate.getPrincipal();
33 // 生成token
34 String token = JwtUtil.generateToken(userDetail.getUsername());
35 return new Response(200, "登录成功",token);
36 }
37}
在这里主要是自己处理了,账号密码的错误提示,用UsernamePasswordAuthenticationToken接受用户的个人信息,这在spring-security里也是这样操作的,然后调用认证管理器AuthenticationManager 进行认证即可,从而进入到UserDatailsService进行一系列的处理,如同表单提交一样的去自动处理,就像我上一章节画的流程图一样。
欢迎大家关注我微信公众号一起学习,探讨!