92国产精品视频_亚洲a级在线观看_国产精品电影观看_国产精品免费观看在线_精品伊人久久97_亚洲人成在线观_尤物九九久久国产精品的特点_成人激情在线播放_成人黄色大片在线免费观看_亚洲成人精品久久久_久久免费视频在线观看_久久精品国产一区_国产一区二区三区18_亚洲欧美中文字幕在线一区_日韩美女中文字幕_日韩视频免费在线

SpringBoot + Shiro + Mybatis-plus + Kaptcha + vue實現權限管理登錄功能

2021-5-13    前端達人

登錄功能

在這里插入圖片描述

使用到的技術

  • shiro
  • Mybatis-plus
  • Springboot
  • kaptcha

參考優秀博文

一個博主做的shiro筆記:https://www.guitu18.com/post/2019/07/26/43.html

引入依賴

 <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </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> <!-- shiro --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.7.0</version> </dependency> <!--mybatis-plus 持久層--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.1</version> </dependency> <!--   整合swagger     --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.8.0</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.8.0</version> </dependency> <!-- kaptcha 驗證碼 --> <dependency> <groupId>com.github.penggle</groupId> <artifactId>kaptcha</artifactId> <version>2.3.2</version> </dependency> </dependencies> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54

配置shiro

package com.unclebb.zlgl.config; import com.unclebb.zlgl.utils.CustomRealm; import org.apache.shiro.authc.credential.HashedCredentialsMatcher; import org.apache.shiro.mgt.DefaultSecurityManager; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.util.ThreadContext; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.HashMap; import java.util.Map; /**
 * @program: zlgl
 * @description: Shiro配置類:將SecurityManager以及Realm都注入到Spring容器中
 * @author: LiuZhiliang
 * @create: 2021-05-10 08:56
 **/ @Configuration public class ShiroConfig { /** 
    * @Description: 代理生成器,需要借助SpringAOP來掃描@RequiresRoles和@RequiresPermissions等注解。生成代理類實現功能增強,從而實現權限控制。需要配合AuthorizationAttributeSourceAdvisor一起使用,否則權限注解無效。
    * @Param:
    * @return:
    * @Author: Liuzhiliang
    * @Date:
    */ @Bean public DefaultAdvisorAutoProxyCreator lifecycleBeanProcessor(){ DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator(); defaultAdvisorAutoProxyCreator.setProxyTargetClass(true); return defaultAdvisorAutoProxyCreator; } /** 
    * @Description:  上面配置的DefaultAdvisorAutoProxyCreator相當于一個切面,下面這個類就相當于切點了,兩個一起才能實現注解權限控制。
    * @Param:  
    * @return:  
    * @Author: Liuzhiliang
    * @Date:  
    */ @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager){ AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor(); advisor.setSecurityManager(securityManager); return advisor; } /**
     * @Description: Filter工廠,設置對應的過濾條件和跳轉條件
     * @Param:
     * @return:
     * @Author: Liuzhiliang
     * @Date:
     */ //權限管理,配置主要是Realm的管理認證 @Bean public DefaultWebSecurityManager securityManager(){ DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(myShiroRealm()); ThreadContext.bind(securityManager); return securityManager; } //將自己的驗證方式加入容器 @Bean public CustomRealm myShiroRealm() { HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(); //加密 matcher.setHashAlgorithmName("md5"); matcher.setHashIterations(1); CustomRealm customRealm = new CustomRealm(); customRealm.setCredentialsMatcher(matcher); return customRealm; } @Bean public ShiroFilterFactoryBean shiroFilter(DefaultSecurityManager securityManager){ ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager); //        Map<String,String> maps = new HashMap<>(); //        maps.put("/logout","logout"); //        maps.put("/**","authc"); //        shiroFilterFactoryBean.setLoginUrl("/login"); //        shiroFilterFactoryBean.setUnauthorizedUrl("/403.html"); //        shiroFilterFactoryBean.setSuccessUrl("/index"); //        shiroFilterFactoryBean.setFilterChainDefinitionMap(maps); return shiroFilterFactoryBean; } } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96

配置swagger

package com.unclebb.zlgl.config; import com.google.common.base.Predicates; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.service.Contact; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; /**
 * @Author unclebb
 * @Description Swagger配置類
 * @Date 2021/5/9
 **/ @Configuration @EnableSwagger2 public class Swagger2Config { @Bean public Docket webApiConfig(){ return new Docket(DocumentationType.SWAGGER_2) .groupName("webApi") .apiInfo(webApiInfo()) .select() //過濾掉admin路徑下的所有頁面 .paths(Predicates.and(PathSelectors.regex("/user/.*"))) //過濾掉所有error或error.*頁面 //.paths(Predicates.not(PathSelectors.regex("/error.*"))) .build(); } private ApiInfo webApiInfo(){ return new ApiInfoBuilder() .title("網站-API文檔") .description("本文檔描述了網站微服務接口定義") .version("1.0") .contact(new Contact("qy", "http://atguigu.com", "55317332@qq.com")) .build(); } } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48

配置kaptcha

package com.unclebb.zlgl.config; import com.google.code.kaptcha.impl.DefaultKaptcha; import com.google.code.kaptcha.util.Config; import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Component; import java.util.Properties; /**
 * @program: zlgl
 * @description: Kaptcha配置類
 * @author: LiuZhiliang
 * @create: 2021-05-12 09:03
 **/ @Component public class KaptchaConfig { @Bean public DefaultKaptcha getKaptcha(){ DefaultKaptcha dk = new DefaultKaptcha(); Properties properties = new Properties(); // 圖片邊框 properties.setProperty("kaptcha.border", "yes"); // 邊框顏色 properties.setProperty("kaptcha.border.color", "105,179,90"); // 字體顏色 properties.setProperty("kaptcha.textproducer.font.color", "red"); // 圖片寬 properties.setProperty("kaptcha.image.width", "110"); // 圖片高 properties.setProperty("kaptcha.image.height", "40"); // 字體大小 properties.setProperty("kaptcha.textproducer.font.size", "30"); // session key properties.setProperty("kaptcha.session.key", "code"); // 驗證碼長度 properties.setProperty("kaptcha.textproducer.char.length", "4"); // 字體 properties.setProperty("kaptcha.textproducer.font.names", "宋體,楷體,微軟雅黑"); Config config = new Config(properties); dk.setConfig(config); return dk; } } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

pojo

User

package com.unclebb.zlgl.pojo; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import java.util.Set; /**
 * @Author unclebb
 * @Description 用戶實體類
 * @Date 2021/5/9
 **/ @Data @TableName(value = "user") public class User { @TableId(value = "id",type = IdType.AUTO)//指定自增策略 private int id; @TableField(value = "username") private String username; @TableField(value = "password") private String password; @TableField(exist = false) private Set<Role> rolesSet; private String salt; } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

Role

package com.unclebb.zlgl.pojo; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import lombok.Data; import java.util.Set; /**
 * @Author unclebb
 * @Description 角色實體類
 * @Date 2021/5/9
 **/ @Data public class Role { @TableId(value = "id",type = IdType.AUTO)//指定自增策略 private int id; @TableField(value = "user_name") private String userName; @TableField(value = "role_name") private String roleName; @TableField(exist = false) private Set<Permission> permissionSet; } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

Permission

package com.unclebb.zlgl.pojo; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import lombok.Data; /**
 * @Author unclebb
 * @Description 權限實體類
 * @Date 2021/5/9
 **/ @Data public class Permission { @TableId(value = "id",type = IdType.AUTO)//指定自增策略 private int id; @TableField(value = "role_name") private String roleName; @TableField(value = "permission_name") private String permissionName; } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

Mapper

基本格式:

package com.unclebb.zlgl.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.unclebb.zlgl.pojo.User; import org.apache.ibatis.annotations.Mapper; /**
 * @Author unclebb
 * @Description 用戶映射
 * @Date 2021/5/9
 **/ @Mapper public interface UserMapper extends BaseMapper<User> { } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

Service

Interface

LoginService

package com.unclebb.zlgl.service; import com.baomidou.mybatisplus.extension.service.IService; import com.unclebb.zlgl.pojo.User; import org.springframework.stereotype.Service; /**
 * @Author unclebb
 * @Description 用戶登錄接口
 * @Date 2021/5/9
 **/ @Service public interface LoginService extends IService<User> { public User getByUsername(String username); } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

RoleService

package com.unclebb.zlgl.service; import com.baomidou.mybatisplus.extension.service.IService; import com.unclebb.zlgl.pojo.Role; import org.springframework.stereotype.Service; import java.util.List; @Service public interface RoleService extends IService<Role> { public List<Role> getRole(String userName); } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

PermissionService

package com.unclebb.zlgl.service; import com.baomidou.mybatisplus.extension.service.IService; import com.unclebb.zlgl.pojo.Permission; import org.springframework.stereotype.Service; import java.util.List; @Service public interface PermissionService extends IService<Permission> { public List<Permission> getPermissions(String roleName); } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

ServiceImpl

LoginServiceImpl

package com.unclebb.zlgl.service.impl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.unclebb.zlgl.mapper.UserMapper; import com.unclebb.zlgl.pojo.Role; import com.unclebb.zlgl.pojo.User; import com.unclebb.zlgl.service.LoginService; import com.unclebb.zlgl.service.PermissionService; import com.unclebb.zlgl.service.RoleService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.HashSet; import java.util.List; import java.util.Set; /**
 * @Author unclebb
 * @Description 登錄實現類
 * @Date 2021/5/9
 **/ @Service public class LoginServiceImpl extends ServiceImpl<UserMapper, User> implements LoginService { @Autowired RoleService roleService; @Override public User getByUsername(String username) { QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.eq("username",username); User user = this.getOne(wrapper); List<Role> roleList = roleService.getRole(user.getUsername()); user.setRolesSet(new HashSet<Role>(roleList)); return user; } } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

RoleServiceImpl

package com.unclebb.zlgl.service.impl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.unclebb.zlgl.mapper.RoleMapper; import com.unclebb.zlgl.pojo.Permission; import com.unclebb.zlgl.pojo.Role; import com.unclebb.zlgl.service.PermissionService; import com.unclebb.zlgl.service.RoleService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.HashSet; import java.util.List; import java.util.Set; /**
 * @program: zlgl
 * @description: Role實現類
 * @author: LiuZhiliang
 * @create: 2021-05-10 16:16
 **/ @Service public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService { @Autowired PermissionService permissionService; @Override public List<Role> getRole(String userName) { QueryWrapper wrapper = new QueryWrapper(); wrapper.eq("user_name",userName); List<Role> roleList = this.list(wrapper); for (Role role:roleList){ List<Permission> permissions = permissionService.getPermissions(role.getRoleName()); role.setPermissionSet(new HashSet<Permission>(permissions)); } return roleList; } } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

PermissionServiceImpl

package com.unclebb.zlgl.service.impl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.unclebb.zlgl.mapper.PermissionMapper; import com.unclebb.zlgl.pojo.Permission; import com.unclebb.zlgl.pojo.User; import com.unclebb.zlgl.service.PermissionService; import org.springframework.stereotype.Service; import java.util.List; import java.util.Set; /**
 * @program: zlgl
 * @description: Permission實現類
 * @author: LiuZhiliang
 * @create: 2021-05-10 16:18
 **/ @Service public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements PermissionService { @Override public List<Permission> getPermissions(String roleName) { QueryWrapper<Permission> wrapper = new QueryWrapper<>(); wrapper.eq("role_name",roleName); return this.list(wrapper); } } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

Controller

package com.unclebb.zlgl.controller; import com.unclebb.zlgl.pojo.Role; import com.unclebb.zlgl.pojo.User; import com.unclebb.zlgl.service.RoleService; import com.unclebb.zlgl.utils.Result; import io.swagger.annotations.ApiOperation; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.authz.AuthorizationException; import org.apache.shiro.session.Session; import org.apache.shiro.subject.Subject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpSession; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; /**
 * @Author unclebb
 * @Description 登錄控制器
 * @Date 2021/5/9
 **/ @RestController public class LoginController { @Autowired RoleService roleService; /** 
    * @Description: 登錄接口 
    * @Param:  
    * @return:  
    * @Author: Liuzhiliang
    * @Date:  
    */ @ApiOperation(value = "登錄接口") @RequestMapping("/user/login") public Result login(@RequestBody User user){ System.out.println("進入/user/login API接口"); if (StringUtils.isEmpty(user.getUsername())||StringUtils.isEmpty(user.getPassword())){ return Result.fail("請輸入用戶名密碼"); } Subject subject = SecurityUtils.getSubject(); Session session = subject.getSession(); Object sessionId = session.getId(); Map ret = new HashMap<String,Object>(); ret.put("token",sessionId); UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(),user.getPassword()); try { //登錄成功 subject.login(token); return Result.ok(ret); } catch (AuthenticationException e) { e.printStackTrace(); //登錄失敗 return Result.fail("用戶名密碼錯誤"); } } /** 
    * @Description: 基本測試接口 
    * @Param:  
    * @return:  
    * @Author: Liuzhiliang
    * @Date:  
    */ @RequestMapping("/user/noauthority") public Result noauthority(){ return Result.fail("沒有權限"); } /** 
    * @Description: 測試session接口 
    * @Param:  
    * @return:  
    * @Author: Liuzhiliang
    * @Date:  
    */ @RequestMapping("/user/demoSession") @ResponseBody public String demoSession(HttpSession session){ System.out.println("測試session"); Enumeration<String> names = session.getAttributeNames(); while (names.hasMoreElements()){ String name = names.nextElement(); Object value = session.getAttribute(name); System.out.println(name + " -------  "+ value); } return "session 取值"; } /** 
    * @Description: 測試session接口 
    * @Param:  
    * @return:  
    * @Author: Liuzhiliang
    * @Date:  
    */ @RequestMapping("/user/demoSession2") @ResponseBody public String demoSession2(){ Subject subject = SecurityUtils.getSubject(); Session session = subject.getSession(); System.out.println(session.getHost()); System.out.println(session.getId()); System.out.println(session.getLastAccessTime().getTime()); System.out.println(session.getTimeout()); System.out.println(session.getAttribute("test")); return "session 取值"; } /** 
    * @Description: 測試session接口 
    * @Param:  
    * @return:  
    * @Author: Liuzhiliang
    * @Date:  
    */ @RequestMapping("/user/checkPermission") @ResponseBody public Result checkPermission(User user){ if (StringUtils.isEmpty(user.getUsername())||StringUtils.isEmpty(user.getPassword())){ return Result.fail("請輸入用戶名密碼"); } Subject subject = SecurityUtils.getSubject(); Session session = subject.getSession(); session.setAttribute("test","test"); UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(),user.getPassword()); token.setRememberMe(true); try { //登錄成功 subject.login(token); } catch (AuthenticationException e) { e.printStackTrace(); //登錄失敗 return Result.fail("用戶名密碼錯誤"); } try { subject.checkRole("admin"); return Result.ok("權限檢查成功"); } catch (AuthorizationException e) { e.printStackTrace(); return Result.fail("檢查權限失敗"); } } /** 
    * @Description: 根據token獲取用戶授權信息接口 
    * @Param:  
    * @return:  
    * @Author: Liuzhiliang
    * @Date:  
    */ @RequestMapping("/user/checkRole") public Result checkRole(@RequestParam String token){ Subject subject = SecurityUtils.getSubject(); Session session = subject.getSession(); List<Role> roleList = null; if (token.equals(session.getId().toString())){ String username = session.getAttribute("org.apache.shiro.subject.support.DefaultSubjectContext_PRINCIPALS_SESSION_KEY").toString(); System.out.println(username); roleList = roleService.getRole(username); } return Result.ok(roleList); } /** 
    * @Description: 測試kaptcha ,獲取驗證碼
    * @Param:  
    * @return:  
    * @Author: Liuzhiliang
    * @Date:  
    */ @RequestMapping("/user/testKaptcha") @ResponseBody public String TestKaptcha(HttpServletRequest request, HttpServletResponse response) throws IOException { byte[] captcha = null; ByteArrayOutputStream out = new ByteArrayOutputStream(); try { // 將生成的驗證碼保存在session中 String createText = defaultKaptcha.createText(); request.getSession().setAttribute("rightCode", createText); BufferedImage bi = defaultKaptcha.createImage(createText); ImageIO.write(bi, "jpg", out); } catch (Exception e) { response.sendError(HttpServletResponse.SC_NOT_FOUND); } captcha = out.toByteArray(); response.setHeader("Cache-Control", "no-store"); response.setHeader("Pragma", "no-cache"); response.setDateHeader("Expires", 0); response.setContentType("image/jpeg"); ServletOutputStream sout = response.getOutputStream(); sout.write(captcha); sout.flush(); sout.close(); return "測試Kaptcha"; } /**
     * 校對驗證碼
     *
     * @param request
     * @param response
     * @return
     */ @RequestMapping(value = "/user/verifyKaptcha") public Result imgvrifyControllerDefaultKaptcha(HttpServletRequest request, HttpServletResponse response) { ModelAndView model = new ModelAndView(); String rightCode = (String) request.getSession().getAttribute("rightCode"); String tryCode = request.getParameter("tryCode"); System.out.println("rightCode:" + rightCode + " ———— tryCode:" + tryCode); if (!rightCode.equals(tryCode)) { model.addObject("info", "驗證碼錯誤,請再輸一次!"); model.setViewName("login"); return Result.fail("驗證碼錯誤"); } else { model.addObject("info", "登陸成功"); model.setViewName("index"); return Result.ok("驗證成功"); } } /** 
    * @Description: 測試 校驗權限 permission 
    * @Param:  
    * @return:  
    * @Author: Liuzhiliang
    * @Date:  
    */ @RequestMapping("/user/testShiroPermission") @RequiresPermissions("user:add") public Result TestShiroPermissions(){ System.out.println("訪問 TestShiroPermissions API"); Subject subject = SecurityUtils.getSubject(); String username = (String) subject.getPrincipal(); System.out.println(username); return Result.ok(username); } /** 
    * @Description: 登出功能API
    * @Param:  
    * @return:  
    * @Author: Liuzhiliang
    * @Date:  
    */ @RequestMapping("/user/logout") public Result logout(){ Subject subject = SecurityUtils.getSubject(); String username = (String) subject.getPrincipal(); subject.logout(); return Result.ok(username); } /** 
    * @Description:  測試校驗 角色 role
    * @Param:  
    * @return:  
    * @Author: Liuzhiliang
    * @Date:  
    */ @RequestMapping("/user/TestRole") @RequiresRoles("admin") public Result TestRole(){ System.out.println("測試TestRole"); return Result.ok("測試Role"); } } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279

util

Result

package com.unclebb.zlgl.utils; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; /**
 * @Author unclebb
 * @Description 統一返回API格式
 * @Date 2021/5/9
 **/ @Data @ApiModel(value = "全局統一返回結果") public class Result<T> { @ApiModelProperty(value = "返回碼") private Integer code; @ApiModelProperty(value = "返回消息") private String message; @ApiModelProperty(value = "返回數據") private T data; public Result(){} public static <T> Result<T> build(T data) { Result<T> result = new Result<T>(); if (data != null) result.setData(data); return result; } public static <T> Result<T> build(T body, ResultCodeEnum resultCodeEnum) { Result<T> result = build(body); result.setCode(resultCodeEnum.getCode()); result.setMessage(resultCodeEnum.getMessage()); return result; } public static<T> Result<T> ok(){ return Result.ok(null); } /**
     * 操作成功
     * @param data
     * @param <T>
     * @return
     */ public static<T> Result<T> ok(T data){ Result<T> result = build(data); return build(data, ResultCodeEnum.SUCCESS); } public static<T> Result<T> fail(){ return Result.fail(null); } /**
     * 操作失敗
     * @param data
     * @param <T>
     * @return
     */ public static<T> Result<T> fail(T data){ Result<T> result = build(data); return build(data, ResultCodeEnum.FAIL); } public Result<T> message(String msg){ this.setMessage(msg); return this; } public Result<T> code(Integer code){ this.setCode(code); return this; } } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81

ResultCode

package com.unclebb.zlgl.utils; import lombok.Getter; /**
 * @Author unclebb
 * @Description API狀態信息
 * @Date 2021/5/9
 **/ @Getter public enum ResultCodeEnum { SUCCESS(200,"成功"), FAIL(201, "失敗"), SERVICE_ERROR(202, "服務異常"), DATA_ERROR(204, "數據異常"), SIGN_ERROR(300, "簽名錯誤"), PAY_PASSWORD_ERROR(401, "支付密碼錯誤"), REPEAT_ERROR(402, "重復提交"), INVEST_AMMOUNT_MORE_ERROR(501, "出借金額已經多余標的金額"), RETURN_AMMOUNT_MORE_ERROR(502, "還款金額不正確"), PROJECT_AMMOUNT_ERROR(503, "標的金額不一致") ; private Integer code; private String message; private ResultCodeEnum(Integer code, String message) { this.code = code; this.message = message; } } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

CustomRealm

package com.unclebb.zlgl.utils; import com.unclebb.zlgl.pojo.Permission; import com.unclebb.zlgl.pojo.Role; import com.unclebb.zlgl.pojo.User; import com.unclebb.zlgl.service.LoginService; 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.authz.SimpleAuthorizationInfo; 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; /**
 * @program: zlgl
 * @description: 自定義Realm
 * @author: LiuZhiliang
 * @create: 2021-05-10 09:09
 **/ public class CustomRealm extends AuthorizingRealm { @Autowired LoginService loginService; /** 
    * @Description: 授權配置
    * @Param:  
    * @return:  
    * @Author: Liuzhiliang
    * @Date:  
    */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { String username = (String) principals.getPrimaryPrincipal(); User user = loginService.getByUsername(username); if (user == null){ return null; }else { SimpleAuthorizationInfo  simpleAuthorizationInfo = new SimpleAuthorizationInfo(); for (Role role : user.getRolesSet()){ simpleAuthorizationInfo.addRole(role.getRoleName()); for (Permission permission : role.getPermissionSet()){ simpleAuthorizationInfo.addStringPermission(permission.getPermissionName()); } } return simpleAuthorizationInfo; } } /** 
    * @Description: 認證配置 
    * @Param:  
    * @return:  
    * @Author: Liuzhiliang
    * @Date:  
    */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { String username = token.getPrincipal().toString(); User user = loginService.getByUsername(username); if (user == null){ return null; }else { //匹配密碼 SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username,user.getPassword(),getName()); simpleAuthenticationInfo.setCredentialsSalt(ByteSource.Util.bytes(user.getSalt())); return simpleAuthenticationInfo; } } } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75

前端代碼

前端我這里直接用了 開源的管理系統框架
附地址:

https://github.com/PanJiaChen/vue-admin-template

運行截圖如下
在這里插入圖片描述
在這里插入圖片描述

完事兒只需要改一下它的 返回狀態碼校驗,配置下跨域就可以了
在這里插入圖片描述

整合驗證碼

驗證碼部分包含兩個API接口

/user/testKaptcha 獲取驗證碼信息
/user/verifyKaptcha 校驗

其中獲取驗證碼圖片信息相當于請求靜態圖片資源,直接將驗證碼圖片的src指向 該接口即可,前端源碼如下:

 <el-image :src="kaptcha" @click="refreshCode()" alt="加載失敗" style="margin-left:10px;height:40px;margin-top:5px"> <div slot="placeholder" class="image-slot"> <i class="el-icon-loading"></i> </div> </el-image> 
  • 1
  • 2
  • 3
  • 4
  • 5

其中路徑定義為:

kaptcha:"http://localhost:8082/user/testKaptcha?t="+ new Date().getTime(), 
  • 1

后面加的時間參數是為了刷新url用的
前端的刷新函數就是將kaptcha重新賦值

 refreshCode(){ console.log("測試切換驗證碼") this.kaptcha = "http://localhost:8082/user/testKaptcha?t="+ new Date().getTime() console.log(this.kaptcha) }, 
  • 1
  • 2
  • 3
  • 4
  • 5

登錄、權限校驗、登出效果如下

登錄

登錄首先會驗證 驗證碼的正確性,登陸成功進入主界面

驗證碼錯誤如下:
在這里插入圖片描述
用戶名密碼錯誤如下:
在這里插入圖片描述
登陸成功后請求校驗角色 校驗成功
在這里插入圖片描述請求校驗權限 校驗成功
在這里插入圖片描述

退出,執行兩次,data為null
在這里插入圖片描述

再次校驗權限,報出異常

在這里插入圖片描述


 藍藍設計建立了UI設計分享群,每天會分享國內外的一些優秀設計,如果有興趣的話,可以進入一起成長學習,請掃碼藍小助,報下信息,藍小助會請您入群。歡迎您加入噢~~希望得到建議咨詢、商務合作,也請與我們聯系。

截屏2021-05-13 上午11.41.03.png


文章來源:csdn   作者:黑胡子大叔的小屋

分享此文一切功德,皆悉回向給文章原作者及眾讀者.
免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯系,我們立即更正或刪除。

藍藍設計m.skdbbs.com )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務

日歷

鏈接

個人資料

藍藍設計的小編 http://m.skdbbs.com

存檔

92国产精品视频_亚洲a级在线观看_国产精品电影观看_国产精品免费观看在线_精品伊人久久97_亚洲人成在线观_尤物九九久久国产精品的特点_成人激情在线播放_成人黄色大片在线免费观看_亚洲成人精品久久久_久久免费视频在线观看_久久精品国产一区_国产一区二区三区18_亚洲欧美中文字幕在线一区_日韩美女中文字幕_日韩视频免费在线
欧美精品七区| 日本精品久久电影| 久久久www免费人成黑人精品| 91黄在线观看| 免费污视频在线观看| 国产精品视频一区二区三区综合| 欧美成人猛片aaaaaaa| 蜜桃视频在线一区| 91成人免费在线| 欧美一级淫片播放口| 美脚丝袜一区二区三区在线观看| 成人免费视频网站入口| 色哟哟在线观看一区二区三区| 国产嫩草在线视频| 成人高清电影网站| 亚洲国产精品精华液ab| 国产精品久久久久桃色tv| 欧美国产1区2区| 国产不卡在线视频| 日韩三区四区| 欧美性xxxx18| 99久久99热这里只有精品| 国产一区精品二区| 国产精品美女免费| 中文亚洲欧美| av免费在线观看网址| 亚洲国产中文字幕| 欧美综合在线第二页| 在线观看免费视频综合| 台湾亚洲精品一区二区tv| 日韩—二三区免费观看av| 在线播放亚洲一区| 3atv在线一区二区三区| 国产一区导航| 中文字幕免费在线观看视频一区| 久久国产婷婷国产香蕉| 欧美野外猛男的大粗鳮| 性欧美长视频免费观看不卡| 亚洲一区二区三区美女| 亚洲人成电影在线播放| 国产日韩欧美一区| 精品一区二区国语对白| 亚洲色图17p| 91蝌蚪国产九色| 欧美电影免费观看完整版| 国产精品一区在线| 卡通欧美亚洲| 羞羞网站在线免费观看| 久久一区激情| 黄色亚洲精品| 国产精品毛片久久久久久久| 成人激情小说网站| 成人午夜视频福利| 好吊妞国产欧美日韩免费观看网站| 婷婷久久一区| 亚洲区一区二| 亚洲日本中文字幕区| 成人性生交大片免费看午夜| a91a精品视频在线观看| 久久成人一区| 亚洲制服丝袜在线| 国内精品免费午夜毛片| 欧美性极品xxxx做受| 视频一区二区国产| 欧美一级视频一区二区| 国产精品18久久久久久久网站| 国产精品欧美久久| 成人欧美一区二区三区| 欧美亚洲国产一区二区三区va| 国产精品免费视频xxxx| 久久久91精品国产一区二区精品| 国产亚洲欧洲在线| 99久久99久久免费精品蜜臀| 国产在线一区二区三区四区| 日韩精品免费视频一区二区三区| 国产亚洲情侣一区二区无| 国产精品久久久久久麻豆一区软件| 亚洲乱亚洲乱妇无码| 大香伊人中文字幕精品| av成人在线播放| 国产精品jizz视频| 国产成人在线看| 91在线看黄| 99成人免费视频| 国产成人精品电影| 日本国产欧美一区二区三区| 日韩有码一区| 136fldh精品导航福利| 亚洲欧美日韩国产综合精品二区| 91久久国产精品91久久性色| www.一区二区| 欧美午夜精品一区二区三区电影| 日韩一区二区欧美| 日日夜夜精品一区| 国产脚交av在线一区二区| 日本精品va在线观看| 欧美三级蜜桃2在线观看| 精品捆绑调教一区二区三区| 9191精品国产综合久久久久久| 成人午夜sm精品久久久久久久| 久久国产人妖系列| 亚洲美女av在线| 亚洲综合自拍| 亚洲一区二区三区高清| 美洲天堂一区二卡三卡四卡视频| 98视频精品全部国产| 日韩在线激情视频| 最爽无遮挡行房视频在线| 亚洲尤物在线视频观看| 激情欧美一区二区| 国产情人综合久久777777| …久久精品99久久香蕉国产| 色综合久久久网| 国产高清一区日本| 久久久精品久久久| 欧美精品久久久久久久免费观看| 日韩免费在线播放| 成人免费看黄yyy456| 国产一区二区三区免费不卡| 精品亚洲一区二区三区在线观看| 国产精品嫩草久久久久| 欧美不卡高清| 少妇视频一区| 欧美理论电影在线精品| 国产精品s色| 欧美三级网址| a√资源在线| 欧美久久久一区| 国产网友自拍视频导航网站在线观看| 亚洲精品福利电影| 国产亚洲激情视频在线| 成人性生交大片免费网站| 国产精品久久波多野结衣| 久久久免费观看视频| 91国内精品野花午夜精品| 最新国产在线拍揄自揄视频| 在线观看欧美成人| 亚洲一区二区偷拍精品| 国产午夜精品一区二区| 国产精品久久久久久久久久小说| 欧美色图国产精品| 国产女人精品视频| 日本一区视频在线观看免费| 欧美日韩成人综合在线一区二区| 精品国产一区二区国模嫣然| 懂色中文一区二区在线播放| 中文字幕乱码中文乱码51精品| 一本高清dvd不卡在线观看| 黄色动漫在线观看| 91情侣偷在线精品国产| 97精品视频在线观看自产线路二| 91吃瓜网在线观看| 色播五月激情综合网| av日韩在线网站| 亚洲男帅同性gay1069| 99电影网电视剧在线观看| 97视频精彩视频在线观看| 精品国产91亚洲一区二区三区www| 亚洲欧洲精品一区二区三区| 欧美高清日韩| 日本一区二区三区中文字幕| 亚洲黄色av一区| 国产日韩一区在线| 欧美成人免费va影院高清|