目录
环境配置
项目相关技术
前端环境搭建:
直接用了黑马的资料
用Nginx搭建,Nginx 就是一个全能型工具,专门解决网站和服务器的 “效率”“稳定”“安全” 问题。
Nginx双击即可启动,默认端口为:80
后端环境搭建:
前后端联动:
这里楼主出了一个问题,在启动项目时,无法登录循环报错,经排查,是因为在.yml文件中数据库的密码错误,修改对应.yml文件中的数据库密码即可
找到文件,修改成自己的密码即可
补充扩展:
application-dev.yml:本地开发环境
application-test.yml:测试环境
application-prod.yml:生产环境
三个文件存放在application.yml同一目录下,其中application.yml存放公共配置
登录功能
登录功能源代码已经实现了,写一下注意的点
jwt令牌
产生原因
克服了传统会话技术(cookie和session)容易增加服务器载荷的弊端
作用
也是用于登录时告诉服务器,自己来过
组成
第一部分 | Header(头) | 记录令牌类型 |
第二部分 | Payload(有效载荷) | 携带用户信息以及过期时间 |
第三部分 | Signature(签名) | 防止Token被篡改(安全性) |
在项目中的使用
/**
* 员工管理
*/
@RestController
@RequestMapping("/admin/employee")
@Slf4j
public class EmployeeController {
@Autowired
private EmployeeService employeeService;
@Autowired
private JwtProperties jwtProperties;
/**
* 登录
*
* @param employeeLoginDTO
* @return
*/
@PostMapping("/login")
public Result<EmployeeLoginVO> login(@RequestBody EmployeeLoginDTO employeeLoginDTO) {
log.info("员工登录:{}", employeeLoginDTO);
Employee employee = employeeService.login(employeeLoginDTO);
//登录成功后,生成jwt令牌
Map<String, Object> claims = new HashMap<>();
claims.put(JwtClaimsConstant.EMP_ID, employee.getId());//创建一个映射,将员工id装进去
String token = JwtUtil.createJWT(//createJWT方法,只需给他jwt配置和员工id映射即可
jwtProperties.getAdminSecretKey(),
jwtProperties.getAdminTtl(),
claims);
EmployeeLoginVO employeeLoginVO = EmployeeLoginVO.builder()
.id(employee.getId())
.userName(employee.getUsername())
.name(employee.getName())
.token(token)
.build();
return Result.success(employeeLoginVO);
}
/**
* 退出
*
* @return
*/
@PostMapping("/logout")
public Result<String> logout() {
return Result.success();
}
}
Nginx
原因
nginx反向代理,做了请求转发
Nginx的好处
- 反向代理,速度快,nginx做了缓存
- 负载均衡,nginx会把请求均匀的分配给服务器
- 后端安全
配置
1.反向代理
2.负载均衡
3.后端安全
完善登录功能
问题
员工表中的密码是明文存储,安全低
思路
使用MD5加密方式对明文密码进行加密
JAVA代码
Spring框架中有所提供
先写后面部分,自动生成前面的用Alt+Enter
导入接口文档
实现前后端分离开发
Swagger
新增员工
注意:当前端提交的数据和实体类中对应的属性差别比较大时,建议用DTO来封装数据
/**
* 增加员工
*/
@PostMapping
@ApiOperation(value = "新增员工")
public Result save(@RequestBody EmployeeDTO employeeDTO) {
employeeService.save(employeeDTO);
return Result.success();
}
@PostMapping | 声明一个接口,专门用来接收 POST 类型的请求 |
@ApiOperation | 描述接口的功能和用途 |
@RequestBody | 将 HTTP 请求的 JSON/XML 等格式的请求体,自动转换为 Java 对象(EmployeeDTO ) |
@Insert("insert into employee (name, username, password, phone, sex, id_number, create_time, update_time, create_user, update_user)" +
"values"+
"(#{name},#{username},#{password},#{phone},#{sex},#{idNumber},#{createTime},#{updateTime},#{createUser},#{updateUser})"
)
void insert(Employee employee);
这里Insert语句可以添加方言的方式让他提示生成
ThreadLocal
用处
为每个线程提供单独一份存储空间,具有线程隔离的效果,只有在线程内才能获取对应的值,线程外则不能访问
代码使用
1.在JwtTokenAdminInterceptor类中捕获到员工ID时上传到ThreadLocal的空间中
//2、校验令牌
try {
log.info("jwt校验:{}", token);
Claims claims = JwtUtil.parseJWT(jwtProperties.getAdminSecretKey(), token);
Long empId = Long.valueOf(claims.get(JwtClaimsConstant.EMP_ID).toString());
log.info("当前员工id:", empId);
//上传到线程空间
BaseContext.setCurrentId(empId);
//3、通过,放行
return true;
} catch (Exception ex) {
//4、不通过,响应401状态码
response.setStatus(401);
return false;
}
2.要用这个id时直接获取
//设置创建人id和修改人id
//BaseContext.getCurrentId()获取之前上传的id
employee.setCreateUser(BaseContext.getCurrentId());
employee.setUpdateUser(BaseContext.getCurrentId());
employeeMapper.insert(employee);