## admin-solution
admin-solution 是一个权限管理系统模板.
* 前端基于 vue-element-admin 进行二次开发.
* 后端采用Java语言, 基于SpringBoot, Shiro, MySQL实现
```java
|
|前端权限控制 --> 动态从后端请求路由
权限控制 --> |
|后端权限控制 --> 进行接口调用访问控制
|
```
### token存储
vue-element-admin 默认是读取body里面的token
```javascript
login({ commit }, userInfo) {
const { username, password } = userInfo
return new Promise((resolve, reject) => {
login({ username: username.trim(), password: password }).then(response => {
const { data } = response
commit('SET_TOKEN', data.token)
setToken(data.token)
resolve()
}).catch(error => {
reject(error)
})
})
```
然后使用该token与后端进行权限验证
```javascript
service.interceptors.request.use(
config => {
// do something before request is sent
return config
},
error => {
// do something with request error
console.log(error) // for debug
return Promise.reject(error)
}
)
```
现在修改成, 后端直接将token存储在cookie header里, 并且设置为httponly
```java
@Configuration
public class ShiroConfig {
// ... 其他设置
public SimpleCookie buildCookie() {
SimpleCookie simpleCookie = new SimpleCookie(TOKEN_NAME);
simpleCookie.setPath("/");
// 对服务器生成的TOKEN设置 HttpOnly 属性. 前端无法读写该TOKEN, 提供系统安全, 防止XSS攻击
simpleCookie.setHttpOnly(true);
// 设置浏览器关闭时失效此Cookie
simpleCookie.setMaxAge(-1);
return simpleCookie;
}
}
```
前端在某些场景中仍然需要做token之类的校验, cookie里的token也取不到, 所以在登录接口的应答报文体里也返回了一个token, 代表登录成功了. 该token只是前端做使用, 不参与后端的校验工作.
### 前端路由
前端路由存储在后端数据库里, 用户登录时向后端请求路由json, 然后前端进行动态添加
```javascript
const actions = {
generateRoutes({ commit }, roles) {
return new Promise(resolve => {
getUserFrontendPermissions().then(response => {
let routeNodes = response.data.routeNodes
importComponent(routeNodes)
commit('SET_ROUTES', routeNodes)
resolve(routeNodes)
})
})
}
}
function importComponent(routeNodes) {
for(var rn of routeNodes) {
if(rn.component == "Layout") {
rn.component = Layout
} else {
let componentPath = rn.component
rn.component = () => import(`@/views/${componentPath}`)
}
if(rn.children && rn.children.length > 0) {
importComponent(rn.children)
}
}
}
```
主要的函数就是`importComponent(routeNodes)`, 采用递归的方式import组件.
> 这里要说明一下, webpack 编译es6 动态引入 import() 时不能传入变量, 但一定要用变量的时候,可以通过字符串模板来提供部分信息给webpack;例如import(`./path/${myFile}`), 这样编译时会编译所有./path下的模块. 参考[在vue中import()语法为什么不能传入变量?](https://segmentfault.com/q/1010000011585257/a-1020000013503169)
### 后端权限验证
后端采用shiro进行权限验证, 这是一个非常有趣的框架, 代码写的结构清晰简单明了 👍
```java
@Configuration
public class ShiroConfig {
/**
* 设置接口权限验证, 目前只针对api接口进行权限验证
*
* @param securityManager
* @return
*/
@Bean(name = "shiroFilter")
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
LOGGER.info("start shiroFilter setting");
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
shiroFilterFactoryBean.setLoginUrl("/");
shiroFilterFactoryBean.setSuccessUrl("/#/dashboard");
shiroFilterFactoryBean.setUnauthorizedUrl("/403");
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
Map<String, Filter> filtersMap = new LinkedHashMap<>();
filtersMap.put("apiAccessControlFilter", new ApiAccessControlFilter());
shiroFilterFactoryBean.setFilters(filtersMap);
filterChainDefinitionMap.put("/static/**", "anon");
filterChainDefinitionMap.put("/#/login/**", "anon");
filterChainDefinitionMap.put("/api/user/auth/login", "anon");
filterChainDefinitionMap.put("/logout", "logout");
filterChainDefinitionMap.put("/api/**", "apiAccessControlFilter");
filterChainDefinitionMap.put("/**", "logFilter");
filterChainDefinitionMap.put("/**", "authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
LOGGER.info("shirFilter config fineshed");
return shiroFilterFactoryBean;
}
}
```
目前是只对`/api/**` 接口进行了权限校验设置
```java
public class ApiAccessControlFilter extends AccessControlFilter {
private static final Logger LOGGER = LoggerFactory.getSystemLogger(ApiAccessControlFilter.class);
@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
// 开发环境中, 如果是OPTIONS预检请求则直接返回true TODO 这里想办法做的更加优雅些, 目前就是个补丁
if (!SpringUtil.isInProduction()
&& request instanceof HttpServletRequest
&& "OPTIONS".equals(((HttpServletRequest) request).getMethod())) {
return true;
}
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
Subject subject = SecurityUtils.getSubject();
boolean isAuthenticated = subject.isAuthenticated();
boolean isPermitted = subject.isPermitted(httpServletRequest.getRequestURI());
LOGGER.info("鉴权完成, isPermitted:{}, isAuthenticated:{}", isPermitted, isAuthenticated);
return isPermitted && isAuthenticated;
}
private void trySetUserLog() {
LoggerLocalCache.INSTANCE.setUser(UserUtil.getCurrentUserName());
}
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse servletResponse) throws Exception {
LOGGER.info("访问被拒绝");
Response response = ResponseCode.AUTH_FAIL.build();
String result = JSON.toJSONString(response);
servletResponse.getOutputStream().write(result.getBytes("UTF8"));
servletResponse.flushBuffer();
return false;
}
}
```
### 跨域问题
前端开发过程中会涉及到跨域问题, 因此需要前端和后端一起修改
前端
```javascript
if (process.env.NODE_ENV === 'development') {
service.defaults.baseURL = 'http://localhost:9900/'
service.defaults.withCredentials = true
}
```
后端
```java
@Configuration
public class ShiroConfig {
@Bean
public CorsFilter corsFilter() {
// CORS配置信息
CorsConfiguration config = new CorsConfiguration();
if (!SpringUtil.isInProduction(applicationContext)) {
LOGGER.info("进行非生产模式CORS配置");
config.addAllowedOrigin("*");
config.setAllowCredentials(true);
config.addAllowedMethod("*");
config.addAllowedHeader("*");
config.addExposedHeader("Set-Cookie");
}
UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
configSource.registerCorsConfiguration("/**", config);
return new CorsFilter(configSource);
}
}
```
这样设置在get请求中没问题, 但是在post请求时会先对请求进行预检发送OPTIONS请求, 因此在上面`权限验证`
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
admin-solution 是一个权限管理系统模板 (208个子文件)
mvnw.cmd 6KB
chunk-elementUI.ded27da0.css 228KB
app.cdcfa8c1.css 9KB
chunk-4de1c2b6.a37cd815.css 5KB
chunk-libs.3dfb7769.css 3KB
chunk-80a76e44.5d540af0.css 2KB
chunk-42d6817a.1f0a69cb.css 115B
.env.development 541B
.DS_Store 6KB
.editorconfig 243B
.eslintignore 34B
.gitignore 907B
.gitignore 381B
.gitignore 256B
index.html 6KB
index.html 620B
user_auth_cookie.http 1KB
favicon.ico 66KB
favicon.ico 66KB
maven-wrapper.jar 50KB
AuthorityController.java 10KB
HttpTraceLogFilter.java 9KB
AbstractLogger.java 8KB
ShiroConfig.java 7KB
MavenWrapperDownloader.java 5KB
BackendPermissionService.java 4KB
AuthControllerTest.java 4KB
RequestCostTimeInterceptor.java 3KB
DatabaseRealm.java 3KB
UserAuthService.java 3KB
ApiAccessControlFilter.java 2KB
AbstractShiroTest.java 2KB
GetUserBackendPermissionsResponse.java 2KB
FrontendPermissionService.java 2KB
RoleService.java 2KB
GetPermissionsResponse.java 2KB
ValidatedExceptionHandler.java 2KB
RoleBackendPermissionRelationMapperTest.java 2KB
BackendPermissionMapperTest.java 2KB
UserRoleRelationMapperTest.java 2KB
UserMapperTest.java 1KB
SpringUtil.java 1KB
FrontendPermission.java 1KB
WebMvcConfiguration.java 1KB
UserService.java 1KB
RoleMapperTest.java 1KB
MessageDigestUtil.java 1KB
AuthController.java 1KB
LoggerLocalCache.java 1KB
ResponseCode.java 1KB
FrontendPermissionMapper.java 1KB
BackendPermissionMapper.java 1KB
TableData.java 1KB
UserUtil.java 1KB
RoleFrontendPermissionRelationMapper.java 1KB
RoleBackendPermissionRelationMapper.java 1KB
AdminServerApplication.java 902B
UserRoleRelationMapper.java 880B
InfoResponse.java 858B
GetRolesResponse.java 847B
GetUsersResponse.java 815B
Response.java 780B
LoginRequest.java 714B
BackendPermission.java 709B
RoleMapper.java 708B
RolePermissionRelation.java 702B
User.java 682B
UserMapper.java 681B
BaseModel.java 680B
UrlPathDic.java 660B
UserRoleRelation.java 654B
LoggerFactory.java 650B
UpdateRolePermissionRequest.java 642B
HttpRequestLogInterceptor.java 631B
SpringStartUp.java 619B
UpdateUserRoleRequest.java 594B
Role.java 499B
AdminServerApplicationTests.java 347B
MessageDigestUtilTest.java 345B
AuthConstant.java 312B
LoginResponse.java 282B
SystemLogger.java 259B
UserLogger.java 257B
permission.jpg 26KB
chunk-elementUI.466ca26e.js 653KB
chunk-libs.e885519c.js 367KB
app.43e6314e.js 44KB
chunk-80a76e44.91d44890.js 14KB
chunk-bcb81af2.57b8473d.js 6KB
chunk-7f35ecd4.e3590c58.js 5KB
vue.config.js 4KB
authority.js 3KB
Breadcrumb.spec.js 3KB
permission.js 2KB
user.js 2KB
chunk-2d0e55b0.0060f6f1.js 2KB
chunk-2d0ba81c.3ab73c2d.js 2KB
index.js 2KB
chunk-2d21a9aa.596e947d.js 2KB
request.js 2KB
共 208 条
- 1
- 2
- 3
资源评论
爱花的程序
- 粉丝: 930
- 资源: 2360
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功