hrm中的jwt认证:需求分析与用户登录
程序员文章站
2022-06-13 20:07:15
...
package com.learn.system;
import com.learn.common.utils.IdWorker;
import com.learn.common.utils.JwtUtils;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.Bean;
//1.配置springboot的包扫描
@SpringBootApplication(scanBasePackages = "com.learn")
//2.配置jpa注解的扫描
@EntityScan(value="com.learn.domain.system")
public class SystemApplication {
/**
* 启动方法
*/
public static void main(String[] args) {
SpringApplication.run(SystemApplication.class,args);
}
@Bean
public IdWorker idWorker() {
return new IdWorker();
}
@Bean
public JwtUtils jwtUtils() {
return new JwtUtils();
}
}
package com.learn.common.utils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.Date;
import java.util.Map;
//@Getter
//@Setter
@ConfigurationProperties("jwt.config")
public class JwtUtils {
//签名私钥
private String key;
//签名的失效时间
private Long ttl;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public Long getTtl() {
return ttl;
}
public void setTtl(Long ttl) {
this.ttl = ttl;
}
/**
* 设置认证token
* id:登录用户id
* subject:登录用户名
*
*/
public String createJwt(String id, String name, Map<String,Object> map) {
//1.设置失效时间
long now = System.currentTimeMillis();//当前毫秒
long exp = now + ttl;
//2.创建jwtBuilder
JwtBuilder jwtBuilder = Jwts.builder().setId(id).setSubject(name)
.setIssuedAt(new Date())
.signWith(SignatureAlgorithm.HS256, key);
//3.根据map设置claims
for(Map.Entry<String,Object> entry : map.entrySet()) {
jwtBuilder.claim(entry.getKey(),entry.getValue());
}
jwtBuilder.setExpiration(new Date(exp));
//4.创建token
String token = jwtBuilder.compact();
return token;
}
/**
* 解析token字符串获取clamis
*/
public Claims parseJwt(String token) {
Claims claims = Jwts.parser().setSigningKey(key).parseClaimsJws(token).getBody();
return claims;
}
}
package com.learn.system.controller;
import com.learn.common.controller.BaseController;
import com.learn.common.entity.PageResult;
import com.learn.common.entity.Result;
import com.learn.common.entity.ResultCode;
import com.learn.common.exception.CommonException;
import com.learn.common.utils.JwtUtils;
import com.learn.domain.system.response.ProfileResult;
import com.learn.domain.system.User;
import com.learn.domain.system.response.UserResult;
import com.learn.system.service.RoleService;
import com.learn.system.service.UserService;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
//1.解决跨域
@CrossOrigin
//2.声明restContoller
@RestController
//3.设置父路径
@RequestMapping(value="/sys")
public class UserController extends BaseController {
@Autowired
private UserService userService;
@Autowired
private JwtUtils jwtUtils;
/**
* 分配角色
*/
@RequestMapping(value = "/user/assignRoles", method = RequestMethod.PUT)
public Result save(@RequestBody Map<String,Object> map) {
//1.获取被分配的用户id
String userId = (String) map.get("id");
//2.获取到角色的id列表
List<String> roleIds = (List<String>) map.get("roleIds");
//3.调用service完成角色分配
userService.assignRoles(userId,roleIds);
return new Result(ResultCode.SUCCESS);
}
/**
* 保存
*/
@RequestMapping(value = "/user", method = RequestMethod.POST)
public Result save(@RequestBody User user) {
//1.设置保存的企业id
user.setCompanyId(companyId);
user.setCompanyName(companyName);
//2.调用service完成保存企业
userService.save(user);
//3.构造返回结果
return new Result(ResultCode.SUCCESS);
}
/**
* 查询企业的部门列表
* 指定企业id
*/
@RequestMapping(value = "/user", method = RequestMethod.GET)
public Result findAll(int page, int size, @RequestParam Map map) {
//1.获取当前的企业id
map.put("companyId",companyId);
//2.完成查询
Page<User> pageUser = userService.findAll(map,page,size);
//3.构造返回结果
PageResult pageResult = new PageResult(pageUser.getTotalElements(),pageUser.getContent());
return new Result(ResultCode.SUCCESS, pageResult);
}
/**
* 根据ID查询user
*/
@RequestMapping(value = "/user/{id}", method = RequestMethod.GET)
public Result findById(@PathVariable(value = "id") String id) {
// 添加 roleIds (用户已经具有的角色id数组)
User user = userService.findById(id);
UserResult userResult = new UserResult(user);
return new Result(ResultCode.SUCCESS, userResult);
}
/**
* 修改User
*/
@RequestMapping(value = "/user/{id}", method = RequestMethod.PUT)
public Result update(@PathVariable(value = "id") String id, @RequestBody User user) {
//1.设置修改的部门id
user.setId(id);
//2.调用service更新
userService.update(user);
return new Result(ResultCode.SUCCESS);
}
/**
* 根据id删除
*/
@RequestMapping(value = "/user/{id}", method = RequestMethod.DELETE)
public Result delete(@PathVariable(value = "id") String id) {
userService.deleteById(id);
return new Result(ResultCode.SUCCESS);
}
/**
* 用户登录
* 1.通过service根据mobile查询用户
* 2.比较password
* 3.生成jwt信息
*
*/
@RequestMapping(value="/login",method = RequestMethod.POST)
public Result login(@RequestBody Map<String,String> loginMap) {
String mobile = loginMap.get("mobile");
String password = loginMap.get("password");
User user = userService.findByMobile(mobile);
//登录失败
if(user == null || !user.getPassword().equals(password)) {
return new Result(ResultCode.MOBILEORPASSWORDERROR);
}else {
//登录成功
Map<String,Object> map = new HashMap<>();
map.put("companyId",user.getCompanyId());
map.put("companyName",user.getCompanyName());
String token = jwtUtils.createJwt(user.getId(), user.getUsername(), map);
return new Result(ResultCode.SUCCESS,token);
}
}
/**
* 用户登录成功之后,获取用户信息
* 1.获取用户id
* 2.根据用户id查询用户
* 3.构建返回值对象
* 4.响应
*/
@RequestMapping(value="/profile",method = RequestMethod.POST)
public Result profile(HttpServletRequest request) throws Exception {
/**
* 从请求头信息中获取token数据
* 1.获取请求头信息:名称=Authorization
* 2.替换Bearer+空格
* 3.解析token
* 4.获取clamis
*/
//1.获取请求头信息:名称=Authorization
String authorization = request.getHeader("Authorization");
if(StringUtils.isEmpty(authorization)) {
throw new CommonException(ResultCode.UNAUTHENTICATED);
}
//2.替换Bearer+空格
String token = authorization.replace("Bearer ","");
//3.解析token
Claims claims = jwtUtils.parseJwt(token);
String userid = claims.getId();
User user = userService.findById(userid);
ProfileResult result = new ProfileResult(user);
return new Result(ResultCode.SUCCESS,result);
}
}
#服务配置
server:
port: 9002
#spring配置
spring:
#1.应用配置
application:
name: ihrm-system #指定服务名
#2.数据库连接池
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8
username: root
password: 123456
#3.JPA
jpa:
database: MySQL
show-sql: true
open-in-view: true
jwt:
config:
key: saas-ihrm
ttl: 3600000
package com.learn.common.entity;
/**
* 公共的返回码
* 返回码code:
* 成功:10000
* 失败:10001
* 未登录:10002
* 未授权:10003
* 抛出异常:99999
*/
public enum ResultCode {
SUCCESS(true,10000,"操作成功!"),
//---系统错误返回码-----
FAIL(false,10001,"操作失败"),
UNAUTHENTICATED(false,10002,"您还未登录"),
UNAUTHORISE(false,10003,"权限不足"),
SERVER_ERROR(false,99999,"抱歉,系统繁忙,请稍后重试!"),
//---用户操作返回码 2xxxx----
MOBILEORPASSWORDERROR(false,20001,"用户名或密码错误");
//---企业操作返回码 3xxxx----
//---权限操作返回码----
//---其他操作返回码----
//操作是否成功
boolean success;
//操作代码
int code;
//提示信息
String message;
ResultCode(boolean success,int code, String message){
this.success = success;
this.code = code;
this.message = message;
}
public boolean success() {
return success;
}
public int code() {
return code;
}
public String message() {
return message;
}
}
package com.learn.system.service;
import com.learn.common.utils.IdWorker;
import com.learn.domain.system.Role;
import com.learn.domain.system.User;
import com.learn.system.dao.RoleDao;
import com.learn.system.dao.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.lang.annotation.Target;
import java.util.*;
@Service
public class UserService {
@Autowired
private UserDao userDao;
@Autowired
private RoleDao roleDao;
@Autowired
private IdWorker idWorker;
/**
* 根据mobile查询用户
*/
public User findByMobile(String mobile) {
return userDao.findByMobile(mobile);
}
/**
* 1.保存用户
*/
public void save(User user) {
//设置主键的值
String id = idWorker.nextId()+"";
user.setPassword("123456");//设置初始密码
user.setEnableState(1);
user.setId(id);
//调用dao保存部门
userDao.save(user);
}
/**
* 2.更新用户
*/
public void update(User user) {
//1.根据id查询部门
User target = userDao.findById(user.getId()).get();
//2.设置部门属性
target.setUsername(user.getUsername());
target.setPassword(user.getPassword());
target.setDepartmentId(user.getDepartmentId());
target.setDepartmentName(user.getDepartmentName());
//3.更新部门
userDao.save(target);
}
/**
* 3.根据id查询用户
*/
public User findById(String id) {
return userDao.findById(id).get();
}
/**
* 4.查询全部用户列表
* 参数:map集合的形式
* hasDept
* departmentId
* companyId
*
*/
public Page findAll(Map<String,Object> map,int page, int size) {
//1.需要查询条件
Specification<User> spec = new Specification<User>() {
/**
* 动态拼接查询条件
* @return
*/
public Predicate toPredicate(Root<User> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
List<Predicate> list = new ArrayList<>();
//根据请求的companyId是否为空构造查询条件
if(!StringUtils.isEmpty(map.get("companyId"))) {
list.add(criteriaBuilder.equal(root.get("companyId").as(String.class),(String)map.get("companyId")));
}
//根据请求的部门id构造查询条件
if(!StringUtils.isEmpty(map.get("departmentId"))) {
list.add(criteriaBuilder.equal(root.get("departmentId").as(String.class),(String)map.get("departmentId")));
}
if(!StringUtils.isEmpty(map.get("hasDept"))) {
//根据请求的hasDept判断 是否分配部门 0未分配(departmentId = null),1 已分配 (departmentId != null)
if("0".equals((String) map.get("hasDept"))) {
list.add(criteriaBuilder.isNull(root.get("departmentId")));
}else {
list.add(criteriaBuilder.isNotNull(root.get("departmentId")));
}
}
return criteriaBuilder.and(list.toArray(new Predicate[list.size()]));
}
};
//2.分页
Page<User> pageUser = userDao.findAll(spec, new PageRequest(page-1, size));
return pageUser;
}
/**
* 5.根据id删除用户
*/
public void deleteById(String id) {
userDao.deleteById(id);
}
/**
* 分配角色
*/
public void assignRoles(String userId,List<String> roleIds) {
//1.根据id查询用户
User user = userDao.findById(userId).get();
//2.设置用户的角色集合
Set<Role> roles = new HashSet<>();
for (String roleId : roleIds) {
Role role = roleDao.findById(roleId).get();
roles.add(role);
}
//设置用户和角色集合的关系
user.setRoles(roles);
//3.更新用户
userDao.save(user);
}
}
package com.learn.system.dao;
import com.learn.domain.system.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
public interface UserDao extends JpaRepository<User,String>,JpaSpecificationExecutor<User> {
public User findByMobile(String mobile);
}
上一篇: MySQL事务处理问题的正确解决
下一篇: Redis数据持久化机制AOF原理分析二
推荐阅读