首先新建一個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地址: