RuoYi(若依开源框架)-前后台分离版-后端流程简单分析
【項目結構】
├── common // 工具類
│ └── annotation // 自定義注解
│ └── config // 全局配置
│ └── constant // 通用常量
│ └── core // 核心控制
│ └── enums // 通用枚舉
│ └── exception // 通用異常
│ └── filter // 過濾器處理
│ └── utils // 通用類處理
├── framework // 框架核心
│ └── aspectj // 注解實現
│ └── config // 系統配置
│ └── datasource // 數據權限
│ └── interceptor // 攔截器
│ └── manager // 異步處理
│ └── security // 權限控制
│ └── web // 前端控制
├── ruoyi-generator // 代碼生成(可移除)
├── ruoyi-quartz // 定時任務(可移除)
├── ruoyi-system // 系統代碼
├── ruoyi-admin // 后臺服務
├── ruoyi-xxxxxx // 其他模塊
-登錄請求過程
前端發起請求:http://127.0.0.1:8080/login
防止重復提交攔截器捕獲
【------------ruoyi-framework\src\main\java\com\ruoyi\framework\interceptor\RepeatSubmitInterceptor.java------------------】
@Override
? ? public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
? ? {
? ? ? ? if (handler instanceof HandlerMethod)
? ? ? ? {
? ? ? ? ? ? HandlerMethod handlerMethod = (HandlerMethod) handler;
? ? ? ? ? ? Method method = handlerMethod.getMethod();
? ? ? ? ? ? RepeatSubmit annotation = method.getAnnotation(RepeatSubmit.class);
? ? ? ? ? ? if (annotation != null)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? if (this.isRepeatSubmit(request))
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? AjaxResult ajaxResult = AjaxResult.error("不允許重復提交,請稍后再試");
? ? ? ? ? ? ? ? ? ? ServletUtils.renderString(response, JSONObject.toJSONString(ajaxResult));
? ? ? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? return true;
? ? ? ? }
? ? ? ? else
? ? ? ? {
? ? ? ? ? ? return super.preHandle(request, response, handler);
? ? ? ? }
? ? }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
【1】請求先進入過濾器,符合要求放行,不符合放行一個空請求
【-------------------ruoyi-common\src\main\java\com\ruoyi\common\filter\RepeatableFilter.java-----------------------】
@Override
? ? public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
? ? ? ? ? ? throws IOException, ServletException
? ? {
? ? ? ? ServletRequest requestWrapper = null;
? ? ? ? if (request instanceof HttpServletRequest
? ? ? ? ? ? ? ? && StringUtils.startsWithIgnoreCase(request.getContentType(), MediaType.APPLICATION_JSON_VALUE))
? ? ? ? {
? ? ? ? ? ? requestWrapper = new RepeatedlyRequestWrapper((HttpServletRequest) request, response);
? ? ? ? }
? ? ? ? if (null == requestWrapper)
? ? ? ? {
? ? ? ? ? ? chain.doFilter(request, response);
? ? ? ? }
? ? ? ? else
? ? ? ? {
? ? ? ? ? ? chain.doFilter(requestWrapper, response);
? ? ? ? }
? ? }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
【2】安全機制捕獲
【-------------------ruoyi-framework\src\main\java\com\ruoyi\framework\config\SecurityConfig.java-----------------------】
?@Override
? ? protected void configure(HttpSecurity httpSecurity) throws Exception
? ? {
? ? ? ? httpSecurity
? ? ? ? ? ? ? ? // CSRF禁用,因為不使用session
? ? ? ? ? ? ? ? .csrf().disable()
? ? ? ? ? ? ? ? // 認證失敗處理類
? ? ? ? ? ? ? ? .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
? ? ? ? ? ? ? ? // 基于token,所以不需要session
? ? ? ? ? ? ? ? .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
? ? ? ? ? ? ? ? // 過濾請求
? ? ? ? ? ? ? ? .authorizeRequests()
? ? ? ? ? ? ? ? // 對于登錄login 驗證碼captchaImage 允許匿名訪問
? ? ? ? ? ? ? ? .antMatchers("/login", "/captchaImage").anonymous()
? ? ? ? ? ? ? ? .antMatchers(
? ? ? ? ? ? ? ? ? ? ? ? HttpMethod.GET,
? ? ? ? ? ? ? ? ? ? ? ? "/",
? ? ? ? ? ? ? ? ? ? ? ? "/*.html",
? ? ? ? ? ? ? ? ? ? ? ? "/**/*.html",
? ? ? ? ? ? ? ? ? ? ? ? "/**/*.css",
? ? ? ? ? ? ? ? ? ? ? ? "/**/*.js",
? ? ? ? ? ? ? ? ? ? ? ? "/profile/**"
? ? ? ? ? ? ? ? ).permitAll()
? ? ? ? ? ? ? ? .antMatchers("/common/download**").anonymous()
? ? ? ? ? ? ? ? .antMatchers("/common/download/resource**").anonymous()
? ? ? ? ? ? ? ? .antMatchers("/swagger-ui.html").anonymous()
? ? ? ? ? ? ? ? .antMatchers("/swagger-resources/**").anonymous()
? ? ? ? ? ? ? ? .antMatchers("/webjars/**").anonymous()
? ? ? ? ? ? ? ? .antMatchers("/*/api-docs").anonymous()
? ? ? ? ? ? ? ? .antMatchers("/druid/**").anonymous()
? ? ? ? ? ? ? ? // 除上面外的所有請求全部需要鑒權認證
? ? ? ? ? ? ? ? .anyRequest().authenticated()
? ? ? ? ? ? ? ? .and()
? ? ? ? ? ? ? ? .headers().frameOptions().disable();
? ? ? ? httpSecurity.logout().logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandler);
? ? ? ? // 添加JWT filter
? ? ? ? httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
? ? ? ? // 添加CORS filter
? ? ? ? httpSecurity.addFilterBefore(corsFilter, JwtAuthenticationTokenFilter.class);
? ? ? ? httpSecurity.addFilterBefore(corsFilter, LogoutFilter.class);
? ? }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
【3】SysLoginController的post方法login獲取到請求,并調用login()方法進行登錄驗證
【-------------------ruoyi-admin\src\main\java\com\ruoyi\web\controller\system\SysLoginController.java-----------------------】
@Autowired
? ? private SysLoginService loginService;
/**
?* 登錄方法
?*
?* @param loginBody 登錄信息
?* @return 結果
?*/
@PostMapping("/login")
public AjaxResult login(@RequestBody LoginBody loginBody)
{
? ? System.out.println("This is login!");
? ? AjaxResult ajax = AjaxResult.success();
? ? // 生成令牌
? ? String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
? ? ? ? ? ? loginBody.getUuid());
? ? ajax.put(Constants.TOKEN, token);
? ? return ajax;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@PostMapping是一個組合注解,是@RequestMapping(method=RequestMethod.POST)的縮寫。
@GetMapping、@PutMapping、@PatchMapping和@DeleteMapping,與@PostMapping實現類似
1
2
【4】SysLoginServicer對請求發來的信息進行驗證,以此調用mapper映射接口完成持久層操作
【5】完成后向前端返回AjaxResult ajax信息
springboot security 安全機制
認證流程:
1、由認證配置WebSecurityConfigurerAdapter的configure(HttpSecurity http)方法進入,添加攔截器addFilterBefore
2、進入攔截器AbstractAuthenticationProcessingFilter的attemptAuthentication方法,指定認證對象AbstractAuthenticationToken
3、進入認證邏輯AuthenticationProvider,根據supports的斷定對認證的目標對象指定對哪個攔截器進行認證,進入具體的認證邏輯方法authenticate
4、認證結果:認證成功后進入攔截器的successfulAuthentication方法;認證失敗后進入攔截器的unsuccessfulAuthentication方法
5、對認證結果進行處理
a.認證成功的邏輯:進入SimpleUrlAuthenticationSuccessHandler的onAuthenticationSuccess方法
b.認證失敗的邏輯:進入SimpleUrlAuthenticationFailureHandler的onAuthenticationFailure方法
6、返回結果給頁面,將數據封裝在ObjectMapper對象中,將會以文本形式返回給客戶端(頁面)
?
總結
以上是生活随笔為你收集整理的RuoYi(若依开源框架)-前后台分离版-后端流程简单分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: RuoYi后台系统权限管理解析
- 下一篇: 若依管理系统——前后端分离版(二)登陆接