springboot+shiro權限管理系統

首先新建一個springboot項目:

model代碼如下:

package com.model;


import java.util.List;

/**
 * @Auther: 澹若水
 * @Date: 2020/01/10/18:41
 * @Description:
 */
public class Users {

    private Integer uid;
    public Integer getUid() {
		return uid;
	}
	public void setUid(Integer uid) {
		this.uid = uid;
	}
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	private String userName;
    private String password;
   
}

mapper代碼:

package com.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.model.Role;
import com.model.Users;
import com.request.LoginRequest;
import com.response.UsersRoleResponse;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

import java.util.List;

/**
 * @Auther: 澹若水
 * @Date: 2020/01/10/18:49
 * @Description:
 */
@Mapper
public interface UsersMapper extends BaseMapper<Users> {

    @Select("select u.userName,r.description,r.role_name from users u,role r,users_role ur where u.uid=ur.users_id and r.rid=ur.role_id")
    List<UsersRoleResponse> findRoleAndUser();

    @Select("select r.rid,r.role_name,r.description from users u,role r,users_role ur where u.uid=ur.users_id and r.rid=ur.role_id")
    List<Role> findRole();
    
    @Select("select * from users where user_name=#{userName} and password=#{password}")
    Users findByNameAndPwd(LoginRequest loginRequest);
    
    @Select("select password from users where user_name=#{userName}")
    String findPwdByName(String userName);
    
    @Select("select r.role_name from users u,role r,users_role ur where u.uid=ur.users_id "
    		+ "and r.rid= ur.role_id and user_name=#{userName}")
    String findRoleNameByUname(String userName);
}

service代碼:

package com.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.mapper.UsersMapper;
import com.model.Role;
import com.model.Users;
import com.request.LoginRequest;
import com.response.UsersRoleResponse;
import com.service.UsersService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * @Auther: 澹若水
 * @Date: 2020/01/19/21:56
 * @Description:
 */
@Service
public class UsersServiceImpl implements UsersService {

    @Autowired
    private UsersMapper usersMapper;
    @Override
    public int insert(Users entity) {
        return usersMapper.insert(entity);
    }

    @Override
    public int deleteById(Serializable id) {
        return usersMapper.deleteById(id);
    }

    @Override
    public int deleteByMap(Map<String, Object> columnMap) {
        return usersMapper.deleteByMap(columnMap);
    }

    @Override
    public int delete(Wrapper<Users> wrapper) {
        return usersMapper.delete(wrapper);
    }

    @Override
    public int deleteBatchIds(Collection<? extends Serializable> idList) {
        return usersMapper.deleteBatchIds(idList);
    }

    @Override
    public int updateById(Users entity) {
        return usersMapper.updateById(entity);
    }

    @Override
    public int update(Users entity, Wrapper<Users> updateWrapper) {
        return usersMapper.update(entity,updateWrapper);
    }

    @Override
    public Users selectById(Serializable id) {
        return (Users) usersMapper.selectById(id);
    }

    @Override
    public List<Users> selectBatchIds(Collection<? extends Serializable> idList) {
        return usersMapper.selectBatchIds(idList);
    }

    @Override
    public List<Users> selectByMap(Map<String, Object> columnMap) {
        return usersMapper.selectByMap(columnMap);
    }

    @Override
    public Users selectOne(Wrapper<Users> queryWrapper) {
        return (Users) usersMapper.selectOne(queryWrapper);
    }

    @Override
    public Integer selectCount(Wrapper<Users> queryWrapper) {
        return usersMapper.selectCount(queryWrapper);
    }

    @Override
    public List<Users> selectList(Wrapper<Users> queryWrapper) {
        return usersMapper.selectList(queryWrapper);
    }

    @Override
    public List<Map<String, Object>> selectMaps(Wrapper<Users> queryWrapper) {
        return usersMapper.selectMaps(queryWrapper);
    }

    @Override
    public List<Object> selectObjs(Wrapper<Users> queryWrapper) {
        return usersMapper.selectObjs(queryWrapper);
    }

    @Override
    public IPage<Users> selectPage(IPage<Users> page, Wrapper<Users> queryWrapper) {
        return usersMapper.selectPage(page,queryWrapper);
    }

    @Override
    public IPage<Map<String, Object>> selectMapsPage(IPage<Users> page, Wrapper<Users> queryWrapper) {
        return usersMapper.selectMapsPage(page,queryWrapper);
    }

    @Override
    public List<UsersRoleResponse> findRoleAndUser() {
        return usersMapper.findRoleAndUser();
    }

    @Override
    public List<Role> findRole() {
        return usersMapper.findRole();
    }

	@Override
	public Users findByNameAndPwd(LoginRequest loginRequest) {
		return usersMapper.findByNameAndPwd(loginRequest);
	}

	@Override
	public String findPwdByName(String userName) {
		return usersMapper.findPwdByName(userName);
	}

	@Override
	public String findRoleNameByUname(String userName) {
		return usersMapper.findRoleNameByUname(userName);
	}
}

controller代碼:

package com.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.commom.Md5Util;
import com.commom.Result;
import com.model.Role;
import com.model.Users;
import com.request.LoginRequest;
import com.response.UsersRoleResponse;
import com.service.UsersService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;

/**
 * @Auther: 澹若水
 * @Date: 2020/01/19/21:46
 * @Description:
 */
@RestController
@RequestMapping(value = "/users")
public class UsersController {

    @Autowired
    private UsersService usersService;
    
    /**
     * 用戶登錄並生成token
     *
     * @param loginRequest
     * @return
     */
    @PostMapping(value = "/login")
    public Result login(LoginRequest loginRequest) {
        String pwd = Md5Util.inputPassToDBPass(loginRequest.getPassword(), Md5Util.SALT);
        loginRequest.setPassword(pwd);
        
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken userToken = new UsernamePasswordToken(loginRequest.getUserName(),pwd);
        
        subject.login(userToken);
        
        Result result = new Result();
        return result.ok(200,"登陸成功");
    }
    /**
     * 查找用戶信息
     * @return
     */
    @GetMapping(value = "/findByName")
    @RequiresPermissions("normal")
    public Users findByName(){
    	//通過shiro裏的token得到用戶信息
        Users users = (Users) SecurityUtils.getSubject().getPrincipal();
        QueryWrapper<Users> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_name",users.getUserName());
        return usersService.selectOne(queryWrapper);
    }

    /**
     * 查找角色信息
     * @return
     */
    @GetMapping(value = "/getRole")
    @RequiresPermissions("admin")
    public Result getRole(){
        List<Role> list = usersService.findRole();
        Result result = new Result();
        return result.ok(list);
    }

    /**
     * 查找用戶角色信息
     * @return
     */
    @GetMapping(value = "/findRoleAndUser")
    @RequiresPermissions("/admin")
    public Result findRoleAndUser(){
        List<UsersRoleResponse> list = usersService.findRoleAndUser();
        Result result = new Result();
        return result.ok(list);
    }
}

BaseService代碼:

package com.Base;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import org.apache.ibatis.annotations.Param;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * @Auther: 澹若水
 * @Date: 2020/01/10/16:02
 * @Description:
 */
public interface BaseService<R ,T> {
    /**
     * 插入一條記錄
     *
     * @param entity 實體對象
     */
    int insert(T entity);

    /**
     * 根據 ID 刪除
     *
     * @param id 主鍵ID
     */
    int deleteById(Serializable id);

    /**
     * 根據 columnMap 條件,刪除記錄
     *
     * @param columnMap 表字段 map 對象
     */
    int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);

    /**
     * 根據 entity 條件,刪除記錄
     *
     * @param wrapper 實體對象封裝操作類(可以爲 null)
     */
    int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);

    /**
     * 刪除(根據ID 批量刪除)
     *
     * @param idList 主鍵ID列表(不能爲 null 以及 empty)
     */
    int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);

    /**
     * 根據 ID 修改
     *
     * @param entity 實體對象
     */
    int updateById(@Param(Constants.ENTITY) T entity);

    /**
     * 根據 whereEntity 條件,更新記錄
     *
     * @param entity        實體對象 (set 條件值,可以爲 null)
     * @param updateWrapper 實體對象封裝操作類(可以爲 null,裏面的 entity 用於生成 where 語句)
     */
    int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper);

    /**
     * 根據 ID 查詢
     *
     * @param id 主鍵ID
     */
    T selectById(Serializable id);

    /**
     * 查詢(根據ID 批量查詢)
     *
     * @param idList 主鍵ID列表(不能爲 null 以及 empty)
     */
    List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);

    /**
     * 查詢(根據 columnMap 條件)
     *
     * @param columnMap 表字段 map 對象
     */
    List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);

    /**
     * 根據 entity 條件,查詢一條記錄
     *
     * @param queryWrapper 實體對象封裝操作類(可以爲 null)
     */
    T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * 根據 Wrapper 條件,查詢總記錄數
     *
     * @param queryWrapper 實體對象封裝操作類(可以爲 null)
     */
    Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * 根據 entity 條件,查詢全部記錄
     *
     * @param queryWrapper 實體對象封裝操作類(可以爲 null)
     */
    List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * 根據 Wrapper 條件,查詢全部記錄
     *
     * @param queryWrapper 實體對象封裝操作類(可以爲 null)
     */
    List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * 根據 Wrapper 條件,查詢全部記錄
     * <p>注意: 只返回第一個字段的值</p>
     *
     * @param queryWrapper 實體對象封裝操作類(可以爲 null)
     */
    List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * 根據 entity 條件,查詢全部記錄(並翻頁)
     *
     * @param page         分頁查詢條件(可以爲 RowBounds.DEFAULT)
     * @param queryWrapper 實體對象封裝操作類(可以爲 null)
     */
    IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * 根據 Wrapper 條件,查詢全部記錄(並翻頁)
     *
     * @param page         分頁查詢條件
     * @param queryWrapper 實體對象封裝操作類
     */
    IPage<Map<String, Object>> selectMapsPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
}

pom.xml文件:

<?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.1.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com</groupId>
	<artifactId>demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>demo</name>
	<description>Demo project for Spring Boot</description>

	<properties>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.30</version>
		</dependency>
		<dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.3.2</version>
        </dependency>
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.8.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>
         <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.1.2</version>
        </dependency>
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
			<exclusions>
				<exclusion>
					<groupId>org.junit.vintage</groupId>
					<artifactId>junit-vintage-engine</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

shiro的兩個配置文件:

package com.config;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
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.springframework.beans.factory.annotation.Autowired;
import com.model.Users;
import com.request.LoginRequest;
import com.service.UsersService;
import java.util.HashSet;
import java.util.Set;

/**
 * 描述:
 *
 * @author danruoshui
 * @create 2020-06-13
 */
public class CustomRealm extends AuthorizingRealm {
	
	@Autowired
	private UsersService usersService;
	
	/**
	 * 此方法是控制權限的,對用的權限爲controller方法上的@RequiresPermissions("admin")
	 */

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        
        Users users = (Users) SecurityUtils.getSubject().getPrincipal();
        
        String name = usersService.findRoleNameByUname(users.getUserName());
       
        Set<String> set = new HashSet<String>();
        set.add(name);
        info.setStringPermissions(set);
        return info;
    }

    /**
     * 
     * 獲取即將需要認證的信息
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("-------身份認證方法--------");
        UsernamePasswordToken user = (UsernamePasswordToken) authenticationToken;
       
        LoginRequest loginRequest = new LoginRequest();
        loginRequest.setUserName(user.getUsername());
        loginRequest.setPassword(String.copyValueOf(user.getPassword()));
        
        Users u = usersService.findByNameAndPwd(loginRequest);
        if (null == u) {
            throw new AccountException("用戶名不正確or密碼不正確");
        }
        return new SimpleAuthenticationInfo(u, u.getPassword(),getName());
    }
}

另一個:

package com.config;


import org.apache.shiro.SecurityUtils;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
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.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 描述:
 *
 * @author danruoshui
 * @create 2020-06-13
 */
@Configuration
public class ShiroConfig {

    @Bean(name = "shiroFilter")
    public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        SecurityUtils.setSecurityManager(securityManager);
        //shiroFilterFactoryBean.setLoginUrl("/login");
        shiroFilterFactoryBean.setUnauthorizedUrl("/notRole");
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
        // <!-- authc:所有url都必須認證通過纔可以訪問; anon:所有url都都可以匿名訪問-->
        filterChainDefinitionMap.put("/webjars/**", "anon");
        filterChainDefinitionMap.put("/login/**", "anon");
        filterChainDefinitionMap.put("/users/**", "anon");
        filterChainDefinitionMap.put("/permission/**", "anon");
        filterChainDefinitionMap.put("/role/**", "anon");
        filterChainDefinitionMap.put("/", "anon");
        filterChainDefinitionMap.put("/front/**", "anon");
        filterChainDefinitionMap.put("/api/**", "anon");

        filterChainDefinitionMap.put("/admin/**", "authc");
        
        //主要這行代碼必須放在所有權限設置的最後,不然會導致所有 url 都被攔截 剩餘的都需要認證
        filterChainDefinitionMap.put("/**", "authc");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;

    }

    @Bean
    public DefaultWebSecurityManager securityManager() {
        DefaultWebSecurityManager defaultSecurityManager = new DefaultWebSecurityManager();
        defaultSecurityManager.setRealm(customRealm());
        return defaultSecurityManager;
    }

    @Bean
    public CustomRealm customRealm() {
        CustomRealm customRealm = new CustomRealm();
        return customRealm;
    }
	@Bean
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }

 /**
     * *
     * 開啓Shiro的註解(如@RequiresRoles,@RequiresPermissions),需藉助SpringAOP掃描使用Shiro註解的類,並在必要時進行安全邏輯驗證
     * *
     * 配置以下兩個bean(DefaultAdvisorAutoProxyCreator(可選)和AuthorizationAttributeSourceAdvisor)即可實現此功能
     * * @return
     */
    @Bean
    @DependsOn({"lifecycleBeanPostProcessor"})
    public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        //設置爲truecontroller就可以通過SecurityUtils.getSubject().getPrincipal()拿到用戶信息
        advisorAutoProxyCreator.setUsePrefix(true);
        return advisorAutoProxyCreator;
    }

    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager());
        return authorizationAttributeSourceAdvisor;
    }

}

properties文件:

redis.ip= 192.168.0.101    ## redis所在的服務器IP
redis.port=6379

#數據源配置
spring.datasource.driverClassName=com.mysql.jdbc.Driver
#在下面3306配置自己的數據庫(自己配置)
spring.datasource.url=jdbc:mysql://localhost:3306/test?useSSL=false&useUnicode=true&characterEncoding=utf-8&autoReconnect=true&serverTimezone=Asia/Shanghai
#數據庫用戶(自己配置)
spring.datasource.username=root
#數據庫密碼(自己配置)
spring.datasource.password=root
spring.datasource.initialSize=20
spring.datasource.minIdle=50
spring.datasource.maxActive=500

## Mybatis 配置
# 配置爲 com.pancm.bean 指向實體類包路徑。
mybatis.typeAliasesPackage=com.model
# 配置爲 classpath 路徑下 mapper 包下,* 代表會掃描所有 xml 文件。
#mybatis.mapperLocations=classpath\:mapper/*.xml

sql腳本:

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for permission
-- ----------------------------
DROP TABLE IF EXISTS `permission`;
CREATE TABLE `permission`  (
  `pid` int(32) NOT NULL AUTO_INCREMENT,
  `name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
  `description` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
  PRIMARY KEY (`pid`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Records of permission
-- ----------------------------
INSERT INTO `permission` VALUES (1, '管理員', '管理員');
INSERT INTO `permission` VALUES (2, '普通用戶', '普通用戶');

SET FOREIGN_KEY_CHECKS = 1;

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for role
-- ----------------------------
DROP TABLE IF EXISTS `role`;
CREATE TABLE `role`  (
  `rid` int(32) NOT NULL AUTO_INCREMENT,
  `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
  `role_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
  PRIMARY KEY (`rid`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Records of role
-- ----------------------------
INSERT INTO `role` VALUES (1, '管理員', 'admin');
INSERT INTO `role` VALUES (2, '普通用戶', 'normal');

SET FOREIGN_KEY_CHECKS = 1;

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for role_permission
-- ----------------------------
DROP TABLE IF EXISTS `role_permission`;
CREATE TABLE `role_permission`  (
  `role_id` int(11) NOT NULL,
  `permission_id` int(11) NOT NULL,
  INDEX `role_id`(`role_id`) USING BTREE,
  INDEX `permission_id`(`permission_id`) USING BTREE,
  CONSTRAINT `role_permission_ibfk_1` FOREIGN KEY (`role_id`) REFERENCES `role` (`rid`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Records of role_permission
-- ----------------------------
INSERT INTO `role_permission` VALUES (1, 1);
INSERT INTO `role_permission` VALUES (1, 2);

SET FOREIGN_KEY_CHECKS = 1;

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for users
-- ----------------------------
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users`  (
  `uid` int(11) NOT NULL AUTO_INCREMENT,
  `user_name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `password` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  PRIMARY KEY (`uid`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Records of users
-- ----------------------------
INSERT INTO `users` VALUES (1, '李四', '717e97ba3fa957264ee919439100efbc');
INSERT INTO `users` VALUES (2, '張三', '717e97ba3fa957264ee919439100efbc');
INSERT INTO `users` VALUES (3, '王五', '3889d8c728157669f3e23c265a3b8227');

SET FOREIGN_KEY_CHECKS = 1;


SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for users_role
-- ----------------------------
DROP TABLE IF EXISTS `users_role`;
CREATE TABLE `users_role`  (
  `users_id` int(11) NOT NULL,
  `role_id` int(11) NOT NULL,
  INDEX `user_id`(`users_id`) USING BTREE,
  INDEX `role_id`(`role_id`) USING BTREE,
  CONSTRAINT `users_role_ibfk_2` FOREIGN KEY (`role_id`) REFERENCES `role` (`rid`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `users_role_ibfk_3` FOREIGN KEY (`users_id`) REFERENCES `users` (`uid`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Records of users_role
-- ----------------------------
INSERT INTO `users_role` VALUES (1, 1);
INSERT INTO `users_role` VALUES (2, 2);
INSERT INTO `users_role` VALUES (3, 2);

SET FOREIGN_KEY_CHECKS = 1;

返回結果集封裝:

package com.commom;


import java.io.Serializable;

import java.util.List;



import com.fasterxml.jackson.databind.JsonNode;

import com.fasterxml.jackson.databind.ObjectMapper;



/**

 * json結果集

 */

public class Result implements Serializable {



    // 定義jackson對象

    private static final ObjectMapper MAPPER = new ObjectMapper();

    public Result() {
    }

// 響應業務狀態

    private Integer status;



    // 響應消息

    private String msg;



    // 響應中的數據

    private Object data;



    public static Result build(Integer status, String msg, Object data) {

        return new Result(status, msg, data);

    }

    public static Result ok(Object data) {

        return new Result(data);

    }
    
    public static Result ok(Integer status,String msg) {

        return new Result(status,msg);

    }



    public static Result fail(Object data,String msg) {

        return new Result(data,msg);

    }

    public static Result build(Integer status, String msg) {

        return new Result(status, msg, null);

    }



    public Result(Integer status, String msg, Object data) {

        this.status = status;

        this.msg = msg;

        this.data = data;

    }

    public Result(Object data,String msg) {

        this.msg = msg;

        this.data = data;

    }



    public Result(Object data) {

        this.status = 200;

        this.msg = "OK";

        this.data = data;

    }



    public Integer getStatus() {

        return status;

    }



    public void setStatus(Integer status) {

        this.status = status;

    }



    public String getMsg() {

        return msg;

    }



    public void setMsg(String msg) {

        this.msg = msg;

    }



    public Object getData() {

        return data;

    }



    public void setData(Object data) {

        this.data = data;

    }



    /**

     * 將json結果集轉化爲Result對象

     *

     * @param jsonData

     *            json數據 傳的是Result的對象的Json字符串

     * @param clazz

     *            TaotaoResult中的object類型

     * @return

     */

    public static Result formatToPojo(String jsonData, Class<?> clazz) {

        try {

            if (clazz == null) {

                return MAPPER.readValue(jsonData, Result.class);

            }

            JsonNode jsonNode = MAPPER.readTree(jsonData);

            JsonNode data = jsonNode.get("data");

            Object obj = null;

            if (clazz != null) {

                if (data.isObject()) {

                    obj = MAPPER.readValue(data.traverse(), clazz);

                } else if (data.isTextual()) {

                    obj = MAPPER.readValue(data.asText(), clazz);

                }

            }

            return build(jsonNode.get("status").intValue(), jsonNode.get("msg").asText(), obj);

        } catch (Exception e) {

            return null;

        }

    }



    /**

     * 沒有object對象的轉化

     *

     * @param json

     * @return

     */

    public static Result format(String json) {

        try {

            return MAPPER.readValue(json, Result.class);

        } catch (Exception e) {

            e.printStackTrace();

        }

        return null;

    }



    /**

     * Object是集合轉化

     *

     * @param jsonData  傳的是Result的對象的Json字符串

     *            json數據

     * @param clazz

     *            集合中的類型

     * @return

     */

    public static Result formatToList(String jsonData, Class<?> clazz) {

        try {

            JsonNode jsonNode = MAPPER.readTree(jsonData);

            JsonNode data = jsonNode.get("data");

            Object obj = null;

            if (data.isArray() && data.size() > 0) {

                obj = MAPPER.readValue(data.traverse(),

                        MAPPER.getTypeFactory().constructCollectionType(List.class, clazz));

            }

            return build(jsonNode.get("status").intValue(), jsonNode.get("msg").asText(), obj);

        } catch (Exception e) {

            return null;

        }

    }

    public static final String CONDITIONS = "_conditions";

}

token工具類:

package com.commom;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;

/**
 * @Author:澹若水
 * @Description: 生成token類
 * @Date:Created in  2018/12/19
 */
public class CreateToken {

    private static final String SECRET = "JKKLJOoasdlfj";
    // token 過期時間: 10天
    private static final int CALENDARFIELD = Calendar.DATE;
    private static final int CALENDARINTERGERVAL = 10;
    /**
     * JWT生成Token.
     *
     * JWT構成: header, payload, signature
     */
    public static String createToken(Map<String, Object> map){
        Date iatDate = new Date();
        Calendar nowTime = Calendar.getInstance();
        nowTime.add(CALENDARFIELD, CALENDARINTERGERVAL);
        Date expiresDate = nowTime.getTime();
        // header Map
        String token = JWT.create().withHeader(map) // header
                .withIssuedAt(iatDate) // sign time
                .withExpiresAt(expiresDate) // expire time
                .sign(Algorithm.HMAC256(SECRET)); // signature
        return token;
    }
    /**
     * 解密Token
     *
     * @param token
     * @return
     */
    public static boolean verifyToken(String token) {
        DecodedJWT jwt = null;
        try {
            JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
            jwt = verifier.verify(token);
        } catch (Exception e) {
            System.out.println("token 校驗失敗, 拋出Token驗證非法異常");
        }
        if (jwt == null) {

            return false;
        }
            return true;
    }
}

MD5加密工具類:

package com.commom;


import org.apache.commons.codec.digest.DigestUtils;

/**
 * @Auther: 澹若水
 * @Date: 2020/1/3
 * @Description: 用於生成MD5 密碼的工具類
 */
public class Md5Util {

    public static String md5(String input) {

        return DigestUtils.md5Hex(input);

    }

    /*固定鹽值*/
    public static final String SALT = "1a2b3c4d";

    /**
     * 第一次md5 :
     * <p>
     * 用於 通過輸入的密碼生成 傳輸的密碼 :方法 通過固定鹽值和明文密碼之間的拼接在生成md5
     *
     * @param password
     * @return
     */

    public static String inputPassToFormPass(String password) {

        String str = "" + SALT.charAt(5) + SALT.charAt(4) + password + SALT.charAt(3) + SALT.charAt(2);

        return md5(str);

    }


    /**
     * 第二次md5 : 通過輸入的密碼和數據庫隨機鹽值 繼續生成 密碼
     *
     * @param input
     * @param salt
     * @return
     */

    public static String formPassToDBPass(String input, String salt) {

        String str = "" + salt.charAt(0) + salt.charAt(2) + input + salt.charAt(5) + salt.charAt(4);

        return md5(str);

    }


    /**
     * 最終調用生成密碼的方法
     */

    public static String inputPassToDBPass(String password, String dbsalt) {

        String FirstMd5 = inputPassToFormPass(password);

        String SecondMd5 = formPassToDBPass(FirstMd5, dbsalt);

        return SecondMd5;

    }

}

完整代碼的demo地址:

https://download.csdn.net/download/danruoshui315/12524610

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章