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