vue.js

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript类库 > vue.js > vue springsecurity权限

vue2+springsecurity权限系统的实现

作者:用户6125466032139

本文主要介绍了vue2+springsecurity权限系统的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

准备内容

新建项目,SpringBoot采用2.7.11,spring-boot-starter-security,vue 2.0

默认会自动启动拦截装置,可以这样取消,先这样配置一下

@SpringBootApplication(exclude = {SecurityAutoConfiguration.class})

JWT 校验用户的凭证(头部,载荷,签证)

引入依赖

<!-- JWT -->
<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.2.0</version>
</dependency>

逻辑:用户登录后,请求头中加一个token参数,如果有则表示可以访问,没有就不能访问,这是一个小测试还是有点缺陷的

SpringSecurity 权限控制

一共有两个最主要拦截器

但拦截器里面的实现需要一些组件来实现分别是

流程图解读:

现在关掉之前的SecurityAutoConfiguration.class,打开是不是直接跳转到了登录页面呢,无法访问接口了

配置 SpringSecurity

先说下创建token的工具类

/**
 * 签发JWT
 *
 * @param id 用户ID
 * @param subject   可以是JSON数据 尽可能少
 * @param ttlMillis 不知道
 * @return 结果
 */
public static String createJWT(String id, String subject, long ttlMillis) {
    SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
    // 获取当前时间毫秒
    long nowMillis = System.currentTimeMillis();
    // 获取当前时间日期类型
    Date now = new Date(nowMillis);
    // 生成一个加密的key
    SecretKey secretKey = generalKey();
    JwtBuilder builder = Jwts.builder()
            .setId(id)
            .setSubject(subject)   // 主题
            .setIssuer("ChiHaiKeJi2016")     // 签发者
            .setIssuedAt(now)   // 签发时间
            .signWith(signatureAlgorithm, secretKey); // 签名算法以及密匙
    if (ttlMillis >= 0) {
        long expMillis = nowMillis + ttlMillis;
        Date expDate = new Date(expMillis);
        builder.setExpiration(expDate); // 过期时间
    }
    return builder.compact();
}
/**
 * 生成jwt token
 * @param username 用户名
 */
public static String genJwtToken(String username) {
    return createJWT(username, username, 60 * 60 * 1000);
}
/**
 * 生成加密Key
 */
public static SecretKey generalKey() {
    // 目前只知道这个方法生成一个key,并用base64解码
    byte[] encodedKey = Base64.decode(JwtConstant.JWT_SECERT);
    // 目前不知道啥意思
    return new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
}

配置信息--新建SecurityConfig

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig {
    // 白名单
    private static final String[] URL_WHITE_LIST = {"/login"};
    @Resource
    private LoginHandler loginHandler;
    // 密码加密方式
    @Bean
    protected PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    @Bean
    protected SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
        // 开启跨域 以及csrf攻击关闭
        httpSecurity.cors().and().csrf().disable()
                // 登录登出配置
                .formLogin()
                // 登录成功接口
                .successHandler(loginHandler)
                // 登录失败的接口
                .failureHandler(loginHandler)
//                .and().logout().logoutSuccessHandler()
                // session禁用配置
                .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) // 无状态,前后端分离
                // 拦截规则配置 // // 白名单内容放行
                .and().authorizeRequests().antMatchers(URL_WHITE_LIST).permitAll()
                // 需要认证
                .anyRequest().authenticated();
        return httpSecurity.build();
    }
}

配置登录失败与成功接口---新建---LoginHandler 处理类

/**
 * 登录成功与失败处理器
 */
@Component
public class LoginHandler implements AuthenticationSuccessHandler, AuthenticationFailureHandler {
    // 登录成功的
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        response.setContentType("application/json;charset=UTF-8");
        ServletOutputStream stream = response.getOutputStream();
        // 获取token
        String token = JwtUtils.genJwtToken("user");
        // 写入数据
        stream.write(JSONUtil.toJsonStr(new Result("登录成功", token)).getBytes());
        stream.flush();
        stream.close();
    }
    // 登录失败的
    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
        response.setContentType("application/json;charset=UTF-8");
        ServletOutputStream stream = response.getOutputStream();
        String message = exception.getMessage();
        if (exception instanceof BadCredentialsException) {
            message = "用户名或者密码错误!";
        }
        stream.write(JSONUtil.toJsonStr(new Result(message)).getBytes(StandardCharsets.UTF_8));
        stream.flush();
        stream.close();
    }
}

在用户service实现类中自定义查询数据库

@Service
public class SysUserServiceImpl implements SysUserService, UserDetailsService {
    @Resource
    private SysUserMapper sysUserMapper;
    // 自定义查询参数是用户名
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        LambdaQueryWrapper<SysUser> sysUserLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sysUserLambdaQueryWrapper.eq(SysUser::getUsername, username);
        SysUser user = sysUserMapper.selectOne(sysUserLambdaQueryWrapper);
        if (user == null) {
            throw new UsernameNotFoundException("用户名或密码错误!");
        } else if ("1".equals(user.getStatus())) {
            throw new UsernameNotFoundException("该用户已被封禁!");
        }
        // 第三个是拥有权限
        return new User(user.getUsername(), user.getPassword(), getUserAuthority());
    }
    // 权限
    private List<GrantedAuthority> getUserAuthority() {
        return new ArrayList<>();
    }
}

再来说下前端,先配置跨域

module.exports = {
  devServer: {
    host: '0.0.0.0', // 可以忽略不写
    port: 8080, // 它是用来修改你打开后的端口号的
    open: true, // 值为 true的话,项目启动时自动打开到浏览器里边, false不会打开
    proxy: {
      '/api': {
        target: 'http://localhost:82', // 跨域请求的公共地址
        ws: false, // 也可以忽略不写,不写不会影响跨域
        changeOrigin: true, // 是否开启跨域,值为 true 就是开启, false 不开启
        pathRewrite: {
          '^/api': ''// 注册全局路径, 但是在你请求的时候前面需要加上 /api
        }
      }
    }
  }
}

配置axios,因为配置了跨域,这个时候可以直接写api了

import axios from 'axios'
const request = axios.create({
  baseURL: '/api' // 因为配置跨域了
})
// 下面这是拦截器,拦截请求,自动加token令牌
request.interceptors.request.use(
  config => {
    config.headers.token = `${localStorage.getItem('token')}`
    return config
  }
)
export default request

说下如何请求前端登录接口POST请求
    登录接口就是login,传入username和password就可以了

export const Login = function (data) {
  return request({
    method: 'post',
    url: 'login',
    data: qs.stringify(data)
  })
}

到此这篇关于vue2+springsecurity权限系统的实现的文章就介绍到这了,更多相关vue springsecurity权限内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文