Vue+Security+Springboot前后端交互

在前后端分离项目中,跨域一直是一个常常存在的事情,那么如何解决这个问题呢,看如下代码。

在springboot项目中的config目录下编写一个全局跨域配置

1:创建一个CorsConfiguration对象,并设置允许的域名、请求头和请求方法;
2:设置允许携带凭证,并添加允许的域名模式;
3:创建一个UrlBasedCorsConfigurationSource对象,并将之前配置的CorsConfiguration对象注册到该对象中;
4:最后返回一个新的CorsFilter对象,该对象使用UrlBasedCorsConfigurationSource对象作为其配置源。
5:这样配置后,该服务就能对来自任何路径的跨域请求进行过滤和处理

package com.aaaa.config;

import org.springframework.web.filter.CorsFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

/**
 * @program: AAA-Springboot-Security-21
 * @description: CrosConfig
 * @author: 七
 * @create: 2024-06-19 22:43
 **/
@SuppressWarnings("all")
@Configuration
public class CrosConfig {
    @Bean
    public CorsFilter corsFilter() {
//跨域配置
        CorsConfiguration corsConfiguration = new CorsConfiguration();
//    允许的域名,不要写*,否则cookie就无法使用了
        corsConfiguration.addAllowedOrigin("http://localhost:8080");
//    允许的请求头
        corsConfiguration.addAllowedHeader("*");
//请求方式
        corsConfiguration.addAllowedMethod("*");
        corsConfiguration.setAllowCredentials(true);
//允许携带凭证
        corsConfiguration.addAllowedOriginPattern("*");

//基于请求路径的跨域配置
        UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();

        //所有的路径都能跨域
        urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);

        return new CorsFilter(urlBasedCorsConfigurationSource);
    }
}

为了实现一个简单的前后端交互登录效果,跨域解决后,要重实现一下userdetailsService,重写一下它里面的loadbyusernam方法,在里面进行登录用户的信息查询,

这个里面的权限信息sql表在之前的security文章中有实例

1:通过@Autowired注解自动注入userMapper对象,用于执行数据库操作。
2:重写loadUserByUsername方法,接收一个用户名作为参数。
3:调用userMapper的selectEmployee方法查询该用户名对应的员工信息,并返回一个Employee对象的List。
4:调用userMapper的selectRole方法查询该员工对应的角色信息,并返回一个Role对象的List。
5:创建一个SimpleGrantedAuthority对象的ArrayList,用于存储用户的权限信息。

6:遍历Role对象的List,将每个角色的名称转换为SimpleGrantedAuthority对象,并添加到list1中。
7:创建一个Integer对象的ArrayList,用于存储角色的ID。
8:遍历Role对象的List,将每个角色的ID添加到list2中。
9:调用userMapper的selectResource方法查询与list2中的角色ID对应的资源信息,并返回一个Resource对象的List。
10:遍历Resource对象的List,将每个资源的名称转换为SimpleGrantedAuthority对象,并添加到list1中。
11:使用用户名、密码和权限信息创建一个User对象,并返回该对象作为查询结果。

package com.aaaa.service;

import com.aaaa.enity.Employee;
import com.aaaa.enity.Resource;
import com.aaaa.enity.Role;
import com.aaaa.mapper.userMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @program: AAA-Springboot-Security-21
 * @description:
 * @author: 七
 * @create: 2024-06-20 10:01
 **/
@SuppressWarnings("all")
@Service
/**
 * 实现UserDetailsService接口,用于加载用户详细信息。
 */
public class userDetiels implements UserDetailsService {
    /**
     * 自动注入用户映射器,用于数据库操作。
     */
    @Autowired
    userMapper userMapper;

    /**
     * 根据用户名加载用户详细信息。
     *
     * @param username 用户名
     * @return UserDetails对象,包含用户信息和权限
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        System.out.println("username:" + username);
        // 根据用户名查询员工信息
        List<Employee> employees = userMapper.selectEmployee(username);
        // 检查用户是否存在
        if (employees.size() < 1) {
            System.out.println("该用户不存在");
        }
        // 根据员工ID查询角色信息
        List<Role> roles = userMapper.selectRole(employees.get(0).getId());
        // 初始化权限列表
        ArrayList<SimpleGrantedAuthority> list1 = new ArrayList<>();
        // 初始化角色ID列表,用于后续查询资源权限
        ArrayList<Integer> list2 = new ArrayList<>();
        // 遍历角色,将角色权限添加到权限列表
        for (Role role : roles) {
            list1.add(new SimpleGrantedAuthority(role.getRole()));
            list2.add(role.getId());
        }
        // 根据角色ID查询资源权限
        List<Resource> resources = userMapper.selectResource(list2);
        // 将资源权限添加到权限列表
        for (Resource resource : resources) {
            list1.add(new SimpleGrantedAuthority(resource.getResource()));
        }
        // 返回User对象,包含用户信息和权限
        return new User(username, employees.get(0).getEmPassword(), list1);
    }
}

自定义完userdetailsService之后

该代码是Spring Security的配置类,用于配置应用程序的安全性。

它继承了WebSecurityConfigurerAdapter,并覆盖了configure方法来设置认证和授权。
通过@Autowired注解自动注入UserDetailsService,用于认证过程中查询用户信息。
在configure(AuthenticationManagerBuilder auth)方法中,配置AuthenticationManagerBuilder以使用自定义的用户详情服务和密码编码器。
在configure(HttpSecurity http)方法中,配置HTTP安全设置,包括表单登录、退出登录、权限不足处理、CORS等。
通过@Override注解覆盖了WebSecurityConfigurerAdapter的其他方法,但没有对其进行修改。
该类还定义了一个printJson方法,用于将Map对象转换为JSON格式,并写入HTTP响应中。
该配置类的作用是为应用程序提供安全配置,包括认证和授权的设置。它使用了Spring Security提供的注解和接口,使得配置过程更加简单和直观。

package com.aaaa.config;


import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import org.springframework.context.annotation.Lazy;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;


import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

/**
 * @program: AAA-Springboot-Security-21
 * @description: MySecurityConfig
 * @author: 七
 * @create: 2024-06-19 23:13
 **/
@SuppressWarnings("all")
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(jsr250Enabled = true, securedEnabled = true, prePostEnabled = true)
public class MySecurityConfig extends WebSecurityConfigurerAdapter {
    /**
     * 自动注入UserDetailsService,用于认证过程中查询用户信息。
     */

    @Autowired
    UserDetailsService userDetailsService;



    /**
     * 配置AuthenticationManagerBuilder,以使用自定义的用户详情服务和密码编码器。
     *
     * @param auth AuthenticationManagerBuilder的实例,用于配置认证逻辑。
     * @throws Exception 如果配置过程中出现错误。
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//        PasswordEncoder passwordEncoder = getPasswordEncoder();
//       auth.inMemoryAuthentication().passwordEncoder(passwordEncoder);
     auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
    }

//    /**
//     * 提供一个@Bean注解的方法来定义一个密码编码器 bean。
//     *
//     * @return 返回一个BCryptPasswordEncoder实例,用于加密和验证用户密码。
//     */
//    @Bean
//    public PasswordEncoder passwordEncoder() {
//        return ;
//    }




    /**
     * 配置HTTP安全设置,用于定制Spring Security的HTTP安全功能。
     * @param http Spring Security的HTTP安全配置对象
     * @throws Exception 如果配置过程中出现异常
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 配置表单登录
        http.formLogin()
                // 定义登录成功处理器
                .successHandler((request, response, authentication) -> {
                    Map map = new HashMap();
                    map.put("code", 200);
                    map.put("msg", "登录成功");
                    map.put("data", authentication.getPrincipal());
                   printJson(response,map);
                   
                })
                // 定义登录失败处理器
                .failureHandler((request, response, exception) -> {
                    Map map = new HashMap();
                    map.put("code", 500);
                    map.put("msg", "登录失败");
                    map.put("data", exception.getMessage());
                    printJson(response,map);

                })
                .loginProcessingUrl("/mylogin").permitAll();
//                .usernameParameter("username").passwordParameter("password");

        // 配置退出登录
        http.logout().logoutSuccessHandler((request, response, authentication) -> {
            Map map = new HashMap();
            map.put("code", 200);
            map.put("msg", "退出成功");
            map.put("data", authentication);
            printJson(response,map);
        });
        // 配置权限不足时的处理
        http.exceptionHandling().accessDeniedHandler((request, response, accessDeniedException) -> {
            Map map = new HashMap();
            map.put("code", 500);
            map.put("msg", "权限不足");
            map.put("data", accessDeniedException.getMessage());
            printJson(response,map);
        });
        // 配置所有请求都需要认证
        http.authorizeRequests().anyRequest().authenticated();//除了放行之外的路径,其他全部需要认证
        // 关闭CSRF保护
        http.csrf().disable();
        // 配置CORS
        http.cors();
    }

    /**
     * 配置Web安全设置,主要处理非Spring MVC的请求。
     * @param web Spring Security的Web安全配置对象
     * @throws Exception 如果配置过程中出现异常
     */



    /**
     * 将Map对象转换为JSON格式,并写入HTTP响应中。
     * @param response HTTP响应对象
     * @param map 要转换为JSON的Map对象
     */
    public void printJson(HttpServletResponse response, Map map) {
        response.setContentType("application/json;charset=utf8");
        ObjectMapper objectMapper = new ObjectMapper();
        String s = null;//转化为JSON数据
        PrintWriter writer = null;

        try {
            s = objectMapper.writeValueAsString(map);
            writer = response.getWriter();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        //给vue响应一个格式,字符编码格式是utf8
        writer.print(s);
        writer.flush();
        writer.close();

    }
}

这时候vue项目中就可以跨域访问路径了,这里的200状态就是security配置文件中返回的状态,如果认证成功就返回200,这里判断如果后端认证成功了,就在这里thi.$router.push()跳转页面,这是一个登录的操作,说白了就是后端拿到的账号密码查询成功就返回200状态码,我这里query:{list:authorlist}是将传过来的用户所拥有的资源通过路径返回了出去给其他页面

1:我这里的post请求为何就一个mylogin,是因为我的vue项目中配置全局axios, http://localhost:8080/这个前缀会在请求路径上直接拼接上去

 this.$http.post(`mylogin`,qs.stringify(this.form)).then(res=>{

              // alert("********走完拦截器之后走的方法******")
              console.log(res)
              if(res.code==200){
                console.log(res.data.authorities)
                var  authoritylist=[]
                for (var i=0;i<res.data.authorities.length;i++){
                  var authority=  res.data.authorities[i].authority
                  if (authority.slice(0,3)!="VIP"){
                    authoritylist.push(authority)
                  }
                }
                this.$router.push({path:"/test",query:{list:authoritylist}})

              }else{
                console.log(res)
                alert("用户名或密码错误")
              }
            })

  • 26
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: vue springboot前后端分离开发实战pdf是一本介绍如何使用VueSpring Boot进行前后端分离开发的实战指南。本书详细讲解了如何使用Vue框架搭建前端应用,以及如何利用Spring Boot框架构建后端应用,旨在帮助读者掌握前后端分离开发的技术和方法。 在这本书中,作者首先介绍了前后端分离开发的概念和背景,解释了为什么前后端分离可以带来更好的开发体验和效率。接着,作者详细介绍了Vue框架的基本概念和使用方法,包括组件化开发、路由管理、状态管理等方面的内容。读者可以通过跟随书中的示例代码,逐步学习并实践Vue框架的应用。 在后半部分,作者重点介绍了Spring Boot框架的使用。读者将学习如何使用Spring Boot快速搭建后端应用,并了解如何通过RESTful API与前端应用进行数据交互。此外,作者还介绍了Spring SecuritySpring Data JPA等常用的配套技术,帮助读者构建安全可靠的后端应用。 本书不仅提供了理论知识,还提供了大量的实战案例和实例代码。读者可以跟随书中的示例项目逐步实践,从而更好地掌握VueSpring Boot的开发技巧。此外,本书还涉及了一些项目管理和部署的内容,帮助读者了解如何将前后端分离的应用部署到生产环境中。 总而言之,vue springboot前后端分离开发实战pdf是一本适合想要学习并实践前后端分离开发的开发人员的实用指南,通过学习本书,读者将获得丰富的知识和经验,能够独立设计和开发前后端分离的应用程序。 ### 回答2: 《Vue SpringBoot前后端分离开发实战PDF》这本书是一本关于前后端分离开发实践的指南。它结合了VueSpringBoot两个流行的开发框架,帮助开发者更好地理解和应用这两个技术。 在书中,作者首先介绍了前后端分离的概念和优势。前后端分离开发可以提高开发效率和协作性,同时也能提供更好的性能和扩展性。然后,作者详细介绍了Vue框架的基本知识和使用方法,包括Vue的搭建、组件的创建和组织等。读者可以通过实际的案例来学习和练习。 接着,作者转向SpringBoot框架的介绍和使用。SpringBoot是一个轻量级的Java开发框架,可以快速构建和部署应用程序。作者讲解了如何使用SpringBoot创建RESTful API,以及如何与Vue前端进行交互。 在书的后半部分,作者提供了一些实战案例和示例代码。这些案例涵盖了常见的前后端分离开发场景,如用户管理、权限控制、数据交互等。通过这些案例,读者可以了解到如何将VueSpringBoot无缝地结合起来,构建强大的应用程序。 总的来说,《Vue SpringBoot前后端分离开发实战PDF》是一本非常实用的书籍。它不仅系统地介绍了VueSpringBoot的基础知识和使用方法,还提供了丰富的实战经验和案例。对于想要掌握前后端分离开发技术的开发者来说,这本书是一个很好的学习资源。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值