spring-security结合jwt和umi(react前端框架)企业级框架之前后端分离最佳实战的小插曲-json模式登录

337 阅读5分钟

前言

众所周知,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进行一系列的处理,如同表单提交一样的去自动处理,就像我上一章节画的流程图一样。

欢迎大家关注我微信公众号一起学习,探讨!

在这里插入图片描述
公众号