目录

1 权限系统:

2  完成登录

2.1 前端布局

2.2 完成后端登录接口

3 登录的bug


1 权限系统:

1.前端使用: vue + elementui + axios + css + html
   2.后端使用: springboot+mybatis-plus +mybatis+druid+shiro+swagger2+redis

2  完成登录

2.1 前端布局

<template><!--这里必须使用一个双标签--><div id="login_box"><div class="img_position"><el-avatar :size="140" :src="imgUrl"></el-avatar></div><el-card class="box-card"><el-form :model="ruleForm" status-icon :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm"><el-form-item label="用户名" prop="name"><el-input type="text" v-model="ruleForm.name" autocomplete="off"></el-input></el-form-item><el-form-item label="密码" prop="password"><el-input type="password" v-model="ruleForm.password" autocomplete="off"></el-input></el-form-item><el-form-item><el-button type="primary"size="mini":plain="true"style="margin-left: 100px;width: 100px">登录</el-button></el-form-item></el-form></el-card></div>
</template><script>export default {name: "Login",data(){return {ruleForm: {name: '',password: ''},rules: {name: [{required: true, message:'用户名不能为空', trigger: 'blur'},{validator:function (rule, value, callback) {axios.get("/qy151_16/emp/check?name="+value).then(function (result) {if(result.data.code === 200){app.imgUrl = result.data.data;callback();}else {app.imgUrl = 'https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png';callback(new Error("用户名不存在"));}})}, trigger: 'blur'}],password: [{required: true, message: '密码不能为空', trigger: 'blur'},]},imgUrl:'https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png'}}}
</script><style>#login_box{position: relative;width: 500px;margin: 250px auto;}#login_box div.img_position{position: absolute;left: 200px;top: -70px;}.text {font-size: 14px;}.item {padding: 18px 0;}.box-card {padding: 100px 50px 0 0;width: 480px;}</style>

(2)登录按钮事件

如果想在vue工程中使用axios进行异步请求,则需要在main.js中导入axios
[1]//导入axios
import axios from "axios";
[2]//把axios挂载到vue对象中,以后在vue中如果使用axios直接可以用$http名称
Vue.prototype.$http=axios

 methods:{login(){//表单校验this.$refs['ruleForm'].validate((valid) => {if(valid){//url:后端登录接口的路径this.$http.post("http://localhost:8808/user/login",this.ruleForm).then(result=>{});}})}}

2.2 完成后端登录接口

(1)依赖

?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.12.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.ykq</groupId><artifactId>qy151-springboot-vue</artifactId><version>0.0.1-SNAPSHOT</version><name>qy151-springboot-vue</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.5.2</version></dependency><dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.31</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.2</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.2.8</version></dependency><dependency><groupId>com.github.xiaoymin</groupId><artifactId>swagger-bootstrap-ui</artifactId><version>1.9.6</version></dependency><dependency><groupId>com.spring4all</groupId><artifactId>swagger-spring-boot-starter</artifactId><version>1.9.1.RELEASE</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.2.2</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins></build></project>

(2)mp的代码生成器

package com.xzj;import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;import java.util.Collections;/*** @author xuan*/
public class Generator {public static void main(String[] args) {FastAutoGenerator.create("jdbc:mysql://localhost:3306/shiro-permission?serverTimezone=Asia/Shanghai", "root", "pAssW0rd").globalConfig(builder -> {builder.author("xzj") // 设置作者.enableSwagger() // 开启 swagger 模式.fileOverride() // 覆盖已生成文件.outputDir(".\\src\\main\\java\\"); // 指定输出目录}).packageConfig(builder -> {builder.parent("com.xzj") // 设置父包名.moduleName("system") // 设置父包模块名.pathInfo(Collections.singletonMap(OutputFile.xml, "src\\main\\resources\\mapper\\")); // 设置mapperXml生成路径}).strategyConfig(builder -> {builder.addInclude("acl_user","acl_role","acl_permission")// 设置需要生成的表名.addTablePrefix("acl_"); // 设置过滤表前缀}).templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板.execute();}
}

(3) 配置application文件

server.port=8808

spring.datasource.druid.url=jdbc:mysql://localhost:3306/shiro-permission?serverTimezone=Asia/Shanghai
spring.datasource.druid.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.druid.username=root
spring.datasource.druid.password=root

#日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

(4)接口

package com.xzj.system.controller;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xzj.system.entity.User;
import com.xzj.system.service.IUserService;
import com.xzj.vo.CommonResult;
import com.xzj.vo.LoginVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.*;import java.util.UUID;
import java.util.concurrent.TimeUnit;/*** @author xuan*/
@RestController
@RequestMapping("/system")
@Api(tags = "登录的接口类")
public class LoginController {@Autowiredprivate IUserService userService;@PostMapping("/login")@ApiOperation(value ="登录接口")public CommonResult login(@RequestBody LoginVo loginVo){QueryWrapper<User> wrapper = new QueryWrapper<>();wrapper.eq("username",loginVo.getUsername());wrapper.eq("password",loginVo.getPassword());wrapper.eq("is_deleted",0);User user = userService.getOne(wrapper);System.out.println(user);if (user!=null){return  new CommonResult(2000,"登录成功",token);}else{return new CommonResult(5000,"登录失败",null);}}
}

前端调用后端登录接口时出现如下的错误

为跨域问题:

当使用异步请求从一个网址访问另一个网址时可能会出现跨域问题。
前提:
   1. 必须为异步请求
   2. 当端口号或协议或ip不同时则会出现跨域

出现两个请求: 有一个请求的方式为: OPTIONS 和真实的请求方式

理解: OPTIONS先头部队。---探视后台有没有解决跨域。

如何解决跨域:

后端解决---->这里也有几种方式:
   【1】可以借助nginx.
   【2】在代码中解决

(origins = {"192.168.0.111:8080","192.168.0.120:8081"},allowedHeaders="运行哪些请求头跨域",methods={"GET","POST"})

origins: 允许哪些域可以跨域访问我这个接口
allowedHeaders:允许哪些请求头信息跨域
methods: 允许哪些请求方式跨域

上面再控制层接口处加上注解的方式解决跨,麻烦的地方就需要对每个控制类都加该注解。 设置一个全局跨域配置类

package com.xzj.system.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;/*** @author xuan*/
@Configuration
public class CorsConfig {// 当前跨域请求最大有效时长。这里默认1天private static final long MAX_AGE = 24 * 60 * 60;@Beanpublic CorsFilter corsFilter() {UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();CorsConfiguration corsConfiguration = new CorsConfiguration();corsConfiguration.addAllowedOrigin("*"); // 1 设置访问源地址corsConfiguration.addAllowedHeader("*"); // 2 设置访问源请求头corsConfiguration.addAllowedMethod("*"); // 3 设置访问源请求方法corsConfiguration.setMaxAge(MAX_AGE);source.registerCorsConfiguration("/**", corsConfiguration); // 4 对接口配置跨域设置return new CorsFilter(source);}}

登录成功后前端路由跳转

3 登录的bug

上面咱们写的登录,后端没有保存数据 前端也没有拿到数据进行保存

修改登录的接口

package com.xzj.system.controller;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xzj.system.entity.User;
import com.xzj.system.service.IUserService;
import com.xzj.vo.CommonResult;
import com.xzj.vo.LoginVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.*;import java.util.UUID;
import java.util.concurrent.TimeUnit;/*** @author xuan*/
@RestController
@RequestMapping("/system")
@Api(tags = "登录的接口类")
public class LoginController {@Autowiredprivate IUserService userService;@Autowiredprivate RedisTemplate redisTemplate;@PostMapping("/login")@ApiOperation(value ="登录接口")public CommonResult login(@RequestBody LoginVo loginVo){QueryWrapper<User> wrapper = new QueryWrapper<>();wrapper.eq("username",loginVo.getUsername());wrapper.eq("password",loginVo.getPassword());wrapper.eq("is_deleted",0);User user = userService.getOne(wrapper);System.out.println(user);if (user!=null){String token = UUID.randomUUID().toString();ValueOperations forValue = redisTemplate.opsForValue();forValue.set(token,user,24, TimeUnit.HOURS);return  new CommonResult(2000,"登录成功",token);}else{return new CommonResult(5000,"登录失败",null);}}
}

修改前端登录方法

后面每次请求都可以携带该token,

每次请求都得要人为添加参数token. 我们可以使用axios得请求拦截器

4 前置路由守卫

前置路由守卫:就是在路由跳转前加上自己得一些业务代码

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import './plugins/element.js'
//导入axios
import axios from "axios";Vue.config.productionTip = false
//设置axios的请求拦截器---在请求头上添加token
axios.interceptors.request.use(config=>{var token = sessionStorage.getItem("token");if(token){config.headers.token=token;}return config;
}),//设置前置路由守卫 to:到哪个路由  from:从哪个路由来  next():放行到指定路由router.beforeEach(((to, from, next) => {//获取跳转得路径var path = to.path;//判断是否为登录路由路径if(path==="/login"){//放行return next();}//其他路由路径 判断是否登录过var token = sessionStorage.getItem("token");if(token){return  next();}//跳转登录return next("/login");}))
// 设置axios基础路径
axios.defaults.baseURL="http://localhost:8808"Vue.prototype.$http =axios
new Vue({router,render: h => h(App)
}).$mount('#app')

5 整合shiro

(1)依赖

<dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring-boot-starter</artifactId>
            <version>1.7.0</version>
        </dependency>

(2) shiro得配置类

package com.xzj.system.config;import com.xzj.system.filter.LoginFilter;
import com.xzj.system.realm.MyRealm;
import com.xzj.system.service.IUserService;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.filter.DelegatingFilterProxy;import javax.servlet.Filter;
import java.util.HashMap;/*** @author xuan*/
@Configuration
public class shiroConfig {@Beanpublic DefaultWebSecurityManager securityManager(){DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();securityManager.setRealm(realm());return securityManager;}@Beanpublic Realm realm(){MyRealm myRealm = new MyRealm();myRealm.setCredentialsMatcher(credentialsMatcher());return  myRealm;}@Beanpublic CredentialsMatcher credentialsMatcher (){HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();credentialsMatcher.setHashAlgorithmName("MD5");credentialsMatcher.setHashIterations(1024);return credentialsMatcher;}@Autowiredprivate RedisTemplate redisTemplate;@Bean(value = "shiroFilter")public ShiroFilterFactoryBean filterFactoryBean(){ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();factoryBean.setSecurityManager(securityManager());HashMap<String, String> map = new HashMap<>();map.put("/system/login","anon");map.put("/*.css","anon");map.put("/doc.html","anon");map.put("/v2/api-docs", "anon");map.put("/configuration/security","anon");map.put("/swagger-resources", "anon");map.put("/configuration/ui", "anon");map.put("/**","authc");factoryBean.setFilterChainDefinitionMap(map);HashMap<String, Filter> filterMap = new HashMap<>();filterMap.put("authc",new LoginFilter(redisTemplate));factoryBean.setFilters(filterMap);return factoryBean;}@Beanpublic FilterRegistrationBean<Filter> filterRegistrationBean(){FilterRegistrationBean<Filter> filterRegistrationBean = new FilterRegistrationBean<>();filterRegistrationBean.setName("shiroFilter");filterRegistrationBean.setFilter(new DelegatingFilterProxy());return filterRegistrationBean;}//开始shiro注解@Beanpublic AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();authorizationAttributeSourceAdvisor.setSecurityManager(securityManager());return authorizationAttributeSourceAdvisor;}@Beanpublic DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator=new DefaultAdvisorAutoProxyCreator();advisorAutoProxyCreator.setProxyTargetClass(true);return advisorAutoProxyCreator;}
}

(3)增加一个realm类对象

package com.xzj.system.realm;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xzj.system.entity.User;
import com.xzj.system.service.IUserService;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;import java.util.List;/*** @author xuan*/
public class MyRealm extends AuthorizingRealm {@Autowiredprivate IUserService userService;@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {//        User user = (User) principalCollection.getPrimaryPrincipal();
//
//        List<String> list = userService.selectByUserId(user.getUserid());
//        if(list!=null&&list.size()>0){
//            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//            info.addStringPermissions(list);
//            return info;//        }return null;}@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {String username = (String) authenticationToken.getPrincipal();QueryWrapper<User> wrapper = new QueryWrapper<>();wrapper.eq("username",username);wrapper.eq("is_deleted",0);User user = userService.getOne(wrapper);if(user!=null){ByteSource credentialsSalt = ByteSource.Util.bytes(user.getSalt());SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getPassword(),credentialsSalt,this.getName());return info;}return null;}
}

(4) 修改controller代码

package com.xzj.system.controller;import com.xzj.system.service.IUserService;
import com.xzj.system.vo.CommonResult;
import com.xzj.system.vo.LoginVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.*;import javax.servlet.http.HttpServletRequest;
import java.util.UUID;
import java.util.concurrent.TimeUnit;/*** @author xuan*/
@RestController
@RequestMapping("/system")
@Api(tags = "登录的接口类")
public class LoginController {@Autowiredprivate IUserService userService;@Autowiredprivate RedisTemplate redisTemplate;@PostMapping("/login")@ApiOperation(value ="登录接口")public CommonResult login(@RequestBody LoginVo loginVo){try{Subject subject = SecurityUtils.getSubject();UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(loginVo.getUsername(), loginVo.getPassword());subject.login(usernamePasswordToken);Object one = subject.getPrincipal();String token = UUID.randomUUID().toString();ValueOperations forValue = redisTemplate.opsForValue();forValue.set(token,one,24, TimeUnit.HOURS);return  new CommonResult(2000,"登录成功",token);}catch (Exception e){return new CommonResult(5000,"登录失败",null);}}@GetMapping("/logout")public CommonResult  logout(HttpServletRequest request){String token = request.getHeader("token");if(redisTemplate.hasKey(token)){redisTemplate.delete(token);return new CommonResult(2000,"退出成功",null);}else{return new CommonResult(5000,"无效的token",null);}}
}

测试登录

登录成功后获取用户信息时出现如下得错误

被shiro得拦截器给拦截器了

package com.xzj.system.filter;import com.fasterxml.jackson.databind.ObjectMapper;
import com.xzj.system.vo.CommonResult;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.springframework.data.redis.core.RedisTemplate;import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.PrintWriter;/*** @author xuan*/
public class LoginFilter extends FormAuthenticationFilter {private RedisTemplate redisTemplate;public LoginFilter(RedisTemplate redisTemplate){this.redisTemplate = redisTemplate;}//当登录成功后执行得方法,如果该方法返回false,则执行onAccessDenied@Overrideprotected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {HttpServletRequest req = (HttpServletRequest) request;//请求方式是否为OPTIONSString method = req.getMethod();if(method!=null && method.equals("OPTIONS")){return  true;}//判断请求头是否有token值String token = req.getHeader("token");if(token!=null&& redisTemplate.hasKey(token)){return  true;}return false;}
//未登录时调用该方法? 为什么进入没有登录方法:// --->第一个请求是OPTIONS,没有携带token  第二个因为前端和后端不是用得同一个session.默认shiro以sessionId为是否登录得标准@Overrideprotected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {response.setContentType("application/json;charset=utf-8");PrintWriter writer = response.getWriter();CommonResult commonResult = new CommonResult(4001,"未登录",null);ObjectMapper objectMapper = new ObjectMapper();String json = objectMapper.writeValueAsString(commonResult);writer.print(json);writer.flush();writer.close();return false;}
}

6 主页得布局

<template><el-container><el-header><span id="logo" style="display: inline-block;width: 50%;height: 100%;float: left" ><a href="https://www.bilibili.com/video/BV14g41197PY/"><img src="../assets/logo.png" height="100%" width="180px"></a></span><span id="avatar" style="float: right"><el-dropdown ><span class="el-dropdown-link" style="margin-top: 10px; display: inline-block;"><el-avatar ></el-avatar></span><el-dropdown-menu slot="dropdown"><el-dropdown-item command="info">个人信息</el-dropdown-item><el-dropdown-item command="logout">退出登录</el-dropdown-item></el-dropdown-menu></el-dropdown></span></el-header><el-container><el-aside width="200px"></el-aside><el-main></el-main></el-container><el-footer>Footer</el-footer></el-container>
</template><script>export default {name: "Home",methods:{getInfo(){this.$http.get("http://localhost:8808/system/user/getInfo").then(result=>{console.log(result)})}}}
</script>
<!--当前vue有效-->
<style>html,body,#app{height: 100%;}body,#app{padding: 0px;margin:0px;}.el-container{height: 100%;}.el-header, .el-footer {background-color: #1F272F;color: #333;line-height: 60px;}.el-aside {background-color: #545c64;color: #333;line-height: 560px;}.el-aside>.el-menu{border: none;}.el-main {background-color: #E9EEF3;color: #333;line-height: 560px;}body > .el-container {margin-bottom: 40px;}.el-container:nth-child(5) .el-aside,.el-container:nth-child(6) .el-aside {line-height: 260px;}.el-container:nth-child(7) .el-aside {line-height: 320px;}
</style>

7 退出

前端

 //拉下得触发事件handleCommand(command){if (command==='logout'){this.$http.get("/system/logout").then(result=>{if(result.data.code===2000){sessionStorage.clear();this.$router.push("/login");}})}}

后端

 @GetMapping("/logout")public CommonResult logout(HttpServletRequest request){String token = request.getHeader("token");if(redisTemplate.hasKey(token)){redisTemplate.delete(token);return new CommonResult(2000,"退出成功",null);}return new CommonResult(5000,"无效得token",null);}

8 查询左侧菜单

(1)前端

initLeftMenu(){this.$http.get("/system/permission/leftMenu").then(result=>{if(result.data.code===2000){this.leftMenus=result.data.data;}})},

(2)后端

@Controller
@RequestMapping("/system/permission")
public class PermissionController {@Autowiredprivate IPermissionService permissionService;@GetMapping("leftMenu")public CommonResult leftMenu(HttpServletRequest request){String token = request.getHeader("token");return permissionService.findPermissionByUserId(token);}}

service 层

package com.xzj.system.service.impl;import com.xzj.system.entity.Permission;
import com.xzj.system.entity.User;
import com.xzj.system.mapper.PermissionMapper;
import com.xzj.system.service.IPermissionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xzj.system.vo.CommonResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;import java.util.ArrayList;
import java.util.List;/*** <p>* 权限 服务实现类* </p>** @author xzj* @since 2022-08-08*/
@Service
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements IPermissionService {@Autowiredprivate PermissionMapper permissionMapper;@Autowiredprivate RedisTemplate redisTemplate;@Overridepublic CommonResult findPermissionByUserId(String token) {//根据token获取用户信息ValueOperations forValue = redisTemplate.opsForValue();User o = (User) forValue.get(token);String id = o.getId();//根据用户id查询该用户具有得权限。List<Permission> permissionList = permissionMapper.selectByUserId(id);//设置层级关系List<Permission> firstMenus  = new ArrayList<>();for (Permission first:permissionList){if(first.getPid().equals("1")){firstMenus.add(first);}}//为一级菜单设置二级菜单for(Permission first: firstMenus){first.setChildren(findChildren(permissionList,first.getId()));}return new CommonResult(2000,"查询成功",firstMenus);}//方法递归public List<Permission> findChildren(List<Permission> permissionList,String id){List<Permission> children = new ArrayList<>();for (Permission p :permissionList){if (p.getPid().equals(id)){children.add(p);}}for (Permission child: children){child.setChildren(findChildren(permissionList,child.getId()));}return children;}
}

springboot-vue前后端分离登录相关推荐

  1. 基于SpringBoot+Vue前后端分离的在线教育平台项目

    基于SpringBoot+Vue前后端分离的在线教育平台项目 赠给有缘人,希望能帮助到你!也请不要吝惜你的大拇指,你的Star.点赞将是对我最大的鼓励与支持! 开源传送门: 后台:Gitee | Gi ...

  2. 网上书城 springboot vue前后端分离

    网上书城 springboot vue前后端分离 文章目录 网上书城 springboot vue前后端分离 前言 一.运行截图 二.pom文件 1.引入库 总结 前言 基于springboot vu ...

  3. 大二期末作孽(SpringBoot+Vue前后端分离博客社区(重构White Hole))

    文章目录 前言 目录 效果演示 前言 由于时间关系,完成度确实不高,而且不签只是完成了客户端,当然目前这样也是已经可以正常使用了,当然有点勉强.不过后续还是会不断的去更新维护的,不过大体的架构是这样的 ...

  4. SpringBoot + Vue前后端分离开发:全局异常处理及统一结果封装

    SpringBoot + Vue前后端分离开发:全局异常处理及统一结果封装 文章目录 SpringBoot + Vue前后端分离开发:全局异常处理及统一结果封装 前后端分离开发中的异常处理 统一结果封 ...

  5. SpringBoot+vue前后端分离博客项目

    SpringBoot+vue前后端分离博客项目 Java后端接口开发 1.前言 2.新建Springboot项目 3.整合mybatis plus 第一步:导入jar包 第二步:然后去写配置文件: 第 ...

  6. SpringBoot+Vue前后端分离,使用SpringSecurity完美处理权限问题(二)

    关注公众号[江南一点雨],专注于 Spring Boot+微服务以及前后端分离等全栈技术,定期视频教程分享,关注后回复 Java ,领取松哥为你精心准备的 Java 干货! 当前后端分离时,权限问题的 ...

  7. 基于springboot+vue前后端分离的婚礼服装租赁系统

    1 简介 今天向大家介绍一个帮助往届学生完成的毕业设计项目,基于springboot+vue前后端分离的婚礼服装租赁系统. 计算机毕业生设计,课程设计需要帮助的可以找我 源码获取------> ...

  8. SpringBoot + Vue 前后端分离(用户信息更新头像上传Markdown图片上传)

    文章目录 前言 用户信息更新 前端发送 后端接口 修改用户头像 前端 前端图片显示 图片上传 完整 代码 后端代码 图片存储 图片上传工具类 图片工具类的配置 工具类实现 效果 Markdown 图片 ...

  9. SpringBoot+Vue前后端分离

    文章目录 前言 一.vue项目创建 二.SpringBoot项目创建 使用IDEA创建一个简单的SpringBoot项目,这里随便百度,参考很多 三.前后端整合 1.vue配置跨域跳转 2.sprin ...

  10. 阿里服务器部署springboot+vue前后端分离项目

    服务器部署springboot+vue前后端分离项目 最近刚刚在实习熟悉公司的业务,所有尝试着自己将项目部署到服务器上.本次部署的项目是Spring Boot+Vue前后端分离项目,后端使用的技术有M ...

最新文章

  1. 推荐7个Mac端冷门但是一发现就无法自拔的软件
  2. OUYA设备的购买和安装
  3. [XA]转:一个关于结对编程(Pair Programming)的讲义
  4. Python常用模块——目录
  5. No_16_0303 Java基础学习第十一天
  6. uva1509(暴力dfs)
  7. 记一次el-input使用的坑
  8. Babylon-AST初探-代码生成(Create)
  9. (01)OpenGL es中只在指定区域渲染view
  10. Chrome浏览器提示您的连接不是私密连接解决办法
  11. 谷歌被曝出滥用苹果后门收集用户数据
  12. 采用open***对两台流量卡arm设备进行通讯(公有云)
  13. HTML+CSS纯静态页面布局的理解(一)
  14. 统计学和python_深入浅出统计学系列python实现
  15. 计算机考研复试面试题整理
  16. 人脸识别数据集---CAS-PEAL-R1
  17. 千树万树梨花开:二叉树的实现以及存储结构
  18. 有哪些文艺而有韵味的句子?
  19. 七大行星排列图片_太阳系九大行星排列顺序(口诀:水金地,火木土,天海)...
  20. python PIL 图像增强

热门文章

  1. Bitvise SSH Client 8.32下载
  2. LZW字典编码(文末附python实现代码)
  3. 大数据技术之数据质量管理
  4. Arcgis 地理坐标系转投影坐标系(WGS84转CGCS2000)
  5. 禁止复制服务器文件夹,远程桌面服务器 禁止复制文件夹
  6. 微信小程序 - Vant weapp UI 框架环境搭建详细教程(Window)
  7. pymysql获取要查询的字段名(列名)
  8. 0基础学RS(三)路由器基本配置
  9. 论文阅读:Personalized Federated Learning with Moreau Envelopes
  10. 分享宝贵的考研心得, 做到这些,考研无惧暗箱操作!