使用sa-token实现权限控制
This commit is contained in:
parent
b1ca1ace25
commit
aa94cb3307
@ -86,11 +86,26 @@
|
||||
<artifactId>springfox-boot-starter</artifactId>
|
||||
<version>3.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- shiro的依赖 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.shiro</groupId>
|
||||
<artifactId>shiro-spring</artifactId>
|
||||
<version>1.9.0</version>
|
||||
</dependency>
|
||||
<!-- sa-token依赖 -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-spring-boot-starter</artifactId>
|
||||
<version>1.30.0</version>
|
||||
</dependency>
|
||||
<!-- Sa-Token 整合 Redis (使用jackson序列化方式) -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-dao-redis-jackson</artifactId>
|
||||
<version>1.30.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
|
@ -0,0 +1,53 @@
|
||||
package xyz.longicorn.driver.config;
|
||||
|
||||
import cn.dev33.satoken.context.SaHolder;
|
||||
import cn.dev33.satoken.filter.SaFilterErrorStrategy;
|
||||
import cn.dev33.satoken.filter.SaServletFilter;
|
||||
import cn.dev33.satoken.router.SaHttpMethod;
|
||||
import cn.dev33.satoken.router.SaRouter;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import xyz.longicorn.driver.dto.ApiResult;
|
||||
|
||||
// 主要处理sa-token的拦截和跨域问题
|
||||
@Configuration
|
||||
public class SaTokenConfig {
|
||||
@Bean
|
||||
public SaServletFilter getSaServletFilter() {
|
||||
return new SaServletFilter()
|
||||
.addExclude(
|
||||
"/druid/**",
|
||||
"/api/user/login",
|
||||
"/api/user/reg",
|
||||
"/api/user/forget",
|
||||
"/api/user/reset",
|
||||
"/swagger**",
|
||||
"/swagger-resources/**",
|
||||
"/v2/api-docs",
|
||||
"/picture/**"
|
||||
)
|
||||
.addExclude("/**")
|
||||
.setError(new SaFilterErrorStrategy() {
|
||||
@Override
|
||||
public Object run(Throwable e) {
|
||||
return ApiResult.error(401, e.getMessage());
|
||||
}
|
||||
})
|
||||
.setBeforeAuth(obj -> {
|
||||
// ---------- 设置跨域响应头 ----------
|
||||
SaHolder.getResponse()
|
||||
// 允许指定域访问跨域资源
|
||||
.setHeader("Access-Control-Allow-Origin", "*")
|
||||
// 允许所有请求方式
|
||||
.setHeader("Access-Control-Allow-Methods", "*")
|
||||
|
||||
// 允许的header参数
|
||||
.setHeader("Access-Control-Allow-Headers", "*");
|
||||
|
||||
// 如果是预检请求,则立即返回到前端
|
||||
SaRouter.match(SaHttpMethod.OPTIONS)
|
||||
.free(r -> System.out.println("--------OPTIONS预检请求,不做处理"))
|
||||
.back();
|
||||
});
|
||||
}
|
||||
}
|
@ -1,5 +1,11 @@
|
||||
package xyz.longicorn.driver.config;
|
||||
|
||||
import cn.dev33.satoken.context.model.SaRequest;
|
||||
import cn.dev33.satoken.context.model.SaResponse;
|
||||
import cn.dev33.satoken.interceptor.SaRouteInterceptor;
|
||||
import cn.dev33.satoken.router.SaRouteFunction;
|
||||
import cn.dev33.satoken.router.SaRouter;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
@ -11,6 +17,42 @@ public class WebConfig implements WebMvcConfigurer {
|
||||
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
// 简单的登录拦截
|
||||
// registry.addInterceptor(new SaRouteInterceptor())
|
||||
// .addPathPatterns("/**") // 要拦截的路由地址
|
||||
// .excludePathPatterns(
|
||||
// "/druid/**",
|
||||
// "/api/user/login",
|
||||
// "/api/user/reg",
|
||||
// "/api/user/forget",
|
||||
// "/api/user/reset",
|
||||
// "/swagger**",
|
||||
// "/swagger-resources/**",
|
||||
// "/v2/api-docs",
|
||||
// "/picture/**"
|
||||
// );
|
||||
// 复杂的权限、登录拦截
|
||||
// registry.addInterceptor(new SaRouteInterceptor(new SaRouteFunction() {
|
||||
// @Override
|
||||
// public void run(SaRequest req, SaResponse res, Object handler) {
|
||||
// // 登录认证 -- 拦截所有路由,并排除/user/doLogin 用于开放登录
|
||||
// SaRouter.match("/**", "/user/doLogin", r -> StpUtil.checkLogin());
|
||||
//
|
||||
// // 角色认证 -- 拦截以 admin 开头的路由,必须具备 admin 角色或者 super-admin 角色才可以通过认证
|
||||
// SaRouter.match("/admin/**", r -> StpUtil.checkRoleOr("admin", "super-admin"));
|
||||
//
|
||||
// // 权限认证 -- 不同模块认证不同权限
|
||||
// SaRouter.match("/user/**", r -> StpUtil.checkPermission("user"));
|
||||
// SaRouter.match("/admin/**", r -> StpUtil.checkPermission("admin"));
|
||||
//
|
||||
// // 甚至你可以随意的写一个打印语句
|
||||
// SaRouter.match("/**", r -> System.out.println("----啦啦啦----"));
|
||||
//
|
||||
// // 连缀写法
|
||||
// SaRouter.match("/**").check(r -> System.out.println("----啦啦啦----"));
|
||||
// }
|
||||
// }))
|
||||
// .addPathPatterns("/**");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,5 +1,6 @@
|
||||
package xyz.longicorn.driver.controller;
|
||||
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParams;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
@ -9,6 +10,7 @@ import xyz.longicorn.driver.dto.ApiResult;
|
||||
import xyz.longicorn.driver.dto.FileItem;
|
||||
import xyz.longicorn.driver.dto.FolderDto;
|
||||
import xyz.longicorn.driver.pojo.FolderInfo;
|
||||
import xyz.longicorn.driver.pojo.UserInfo;
|
||||
import xyz.longicorn.driver.service.FolderService;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
@ -26,8 +28,10 @@ public class FolderController {
|
||||
//接口文档的名称
|
||||
@ApiOperation(value = "查询目录信息", notes = "查询相应目录下的所有文件(夹)信息", httpMethod = "GET")
|
||||
public ApiResult listFolder(@RequestParam(required = false, defaultValue = "/") String folderPath) {
|
||||
UserInfo info = StpUtil.getSession().get("user", new UserInfo().setId(0));
|
||||
|
||||
return ApiResult.success(
|
||||
folderService.listFolder(1, folderPath)
|
||||
folderService.listFolder(StpUtil.getLoginId(0), folderPath)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ public class UserController {
|
||||
@SneakyThrows
|
||||
@PostMapping("/login")
|
||||
public ApiResult login(@Validated @RequestBody LoginModel model) {
|
||||
Thread.sleep(5);
|
||||
Thread.sleep(3);
|
||||
final LoginUser user = userService.login(model.getUsername(), model.getPassword());
|
||||
|
||||
return ApiResult.success(user);
|
||||
|
@ -8,6 +8,7 @@ import lombok.NoArgsConstructor;
|
||||
import lombok.ToString;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
@ -15,7 +16,7 @@ import java.util.Date;
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Accessors(chain = true)
|
||||
public class UserInfo {
|
||||
public class UserInfo implements Serializable {
|
||||
|
||||
private Integer id;
|
||||
private String nickname;
|
||||
|
@ -1,5 +1,6 @@
|
||||
package xyz.longicorn.driver.service;
|
||||
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
@ -44,9 +45,12 @@ public class UserService extends ServiceImpl<UserInfoMapper, UserInfo> {
|
||||
// 将登录数据保存到redis 用户后续判断
|
||||
LoginUser user = new LoginUser();
|
||||
user.setAccount(account);
|
||||
StpUtil.login(userInfo.getId()); // 使用用户编号在sa-token 完成登录
|
||||
StpUtil.getSession().set("user",userInfo);
|
||||
// 生成接口需要的token
|
||||
user.setToken(IdUtil.fastSimpleUUID()); // 可以使用jwt生成token
|
||||
loginUserDao.save(user); // 保存用户登录信息到redis
|
||||
// user.setToken(IdUtil.fastSimpleUUID()); // 可以使用jwt生成token
|
||||
user.setToken(StpUtil.getTokenValue());
|
||||
// loginUserDao.save(user); // 保存用户登录信息到redis
|
||||
user.setUserInfo(userInfo);
|
||||
return user;
|
||||
}
|
||||
|
@ -15,7 +15,6 @@ import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Configuration
|
||||
public class ShiroConfig {
|
||||
@Resource
|
||||
private LoginUserDao loginUserDao;
|
||||
|
@ -71,3 +71,5 @@ mybatis-plus:
|
||||
# 实体类所在的包
|
||||
type-aliases-package: xyz.longicorn.driver.pojo
|
||||
type-enums-package: xyz.longicorn.driver.pojo.enums
|
||||
sa-token:
|
||||
token-name: Authorization
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<span style="display:inline-block">
|
||||
<el-image v-if="type == 'picture'" ref="img"
|
||||
:src="currentSrc" :previewSrcList="[currentPreview]"
|
||||
:src="currentSrc"
|
||||
:initial-index="4" fit="cover" :hide-on-click-modal="true"
|
||||
/>
|
||||
<img v-else class="file-icon" :src="currentSrc"/>
|
||||
|
@ -6,10 +6,10 @@
|
||||
<div v-else>
|
||||
<el-breadcrumb separator="/" style="line-height: 30px">
|
||||
<el-breadcrumb-item>
|
||||
<a href="#?path=/">全部文件</a>
|
||||
<router-link to="?path=/">全部文件</router-link>
|
||||
</el-breadcrumb-item>
|
||||
<el-breadcrumb-item v-for="p in currentPathList" :key="p.path">
|
||||
<a v-if="p.path" :href="'#?path=' + p.path">{{ p.name }}</a>
|
||||
<router-link v-if="p.path" :to="'?path=' + p.path">{{ p.name }}</router-link>
|
||||
<span v-else>{{ p.name }}</span>
|
||||
</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
@ -202,6 +202,12 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
'$route'(){
|
||||
// console.log(this.$route)
|
||||
this.handleHashChange();
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
currentPathList() {
|
||||
if (this.currentPath == '/') return []
|
||||
@ -220,12 +226,12 @@ export default {
|
||||
components: {FileBlockItem, FileIcon, ArrowDown, Grid, FolderAdd},
|
||||
mounted() {
|
||||
console.log('记载所有的文件')
|
||||
window.addEventListener('popstate',()=>console.log(location.href))
|
||||
window.addEventListener('hashchange', this.handleHashChange) // 添加监听
|
||||
// window.addEventListener('popstate',()=>console.log(location.href))
|
||||
// window.addEventListener('hashchange', this.handleHashChange) // 添加监听
|
||||
this.handleHashChange();
|
||||
},
|
||||
unmounted() {
|
||||
window.removeEventListener('hashchange', this.handleHashChange); // 取消监听
|
||||
// window.removeEventListener('hashchange', this.handleHashChange); // 取消监听
|
||||
},
|
||||
methods: {
|
||||
// 加载目录下的所有文件
|
||||
@ -242,8 +248,8 @@ export default {
|
||||
},
|
||||
// 获取获取当前目录路径
|
||||
getCurrentPath() {
|
||||
const hash = location.hash;
|
||||
const params = qs.parse(hash.substr(2))
|
||||
const query = this.$route.query;
|
||||
const params = qs.parse(query)
|
||||
return params.path || '/';
|
||||
},
|
||||
//记载所有的子文件
|
||||
|
Loading…
x
Reference in New Issue
Block a user