1、需求分析
###1.1 页面原型效果
###1.2 相关的表结构
sys_user表如下:
###1.3 访问接口定义
请求接口:/api/login
请求方式:POST
请求数据示例:
{
username:'zhangsan',//用户名
password:'666',//密码
code:'1234' //校验码
}
响应数据:
{
"code": 1,//成功1 失败0
"data": { //data为响应的具体数据,不同的接口,data数据格式可能会不同
"id":"1237365636208922624",
"username":"zhangsan",
"nickName":"xiaozhang",
"phone":"1886702304"
}
}
请求参数:
参数名称 | 参数说明 | 是否必须 | 数据类型 | 备注 |
---|---|---|---|---|
用户名 | username | true | string | |
密码 | password | true | string | |
校验码 | code | true | string | 配置校验码功能 |
1.4 封装请求和响应vo
在stock_backend工程下构建构建包:
com.itheima.stock.vo
├── req # 请求数据封装类
└── resp # 响应数据封装类
vo对象直接在:day01\资料\vo导入即可;
package com.itheima.stock.vo.req;
import lombok.Data;
/**
* @author by itheima
* @Date 2021/12/30
* @Description 登录请求vo
*/
@Data
public class LoginReqVo {
/**
* 用户名
*/
private String username;
/**
* 密码
*/
private String password;
/**
* 验证码
*/
private String code;
}
登录响应vo工程导入:day01\资料\LoginRespVo.java
package com.itheima.stock.vo.resp;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
/**
* @author by itheima
* @Date 2021/12/24
* @Description 登录后响应前端的vo
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class LoginRespVo {
/**
* 用户ID
* 将Long类型数字进行json格式转化时,转成String格式类型
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
/**
* 电话
*/
private String phone;
/**
* 用户名
*/
private String username;
/**
* 昵称
*/
private String nickName;
}
2、登录功能开发实现
2.1 配置密码加密匹配器
引入依赖资源:
<!--密码加密和校验工具包-->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-crypto</artifactId>
</dependency>
配置密码加密匹配bean:
package com.itheima.stock.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
/**
* @author by itheima
* @Date 2021/12/30
* @Description 定义公共配置类
*/
@Configuration
public class CommonConfig {
/**
* 密码加密器
* BCryptPasswordEncoder方法采用SHA-256对密码进行加密
* @return
*/
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
}
密码加密测试:
@SpringBootTest
public class TestAll {
@Autowired
private PasswordEncoder passwordEncoder;
@Test
public void testPwd(){
String pwd="1234";
//加密 $2a$10$WAWV.QEykot8sHQi6FqqDOAnevkluOZJqZJ5YPxSnVVWqvuhx88Ha
String encode = passwordEncoder.encode(pwd);
System.out.println(encode);
/*
matches()匹配明文密码和加密后密码是否匹配,如果匹配,返回true,否则false
just test
*/
boolean flag = passwordEncoder.matches(pwd,"$2a$10$WAWV.QEykot8sHQi6FqqDOAnevkluOZJqZJ5YPxSnVVWqvuhx88Ha");
System.out.println(flag);
}
}
2.2 登录接口方法定义
package com.itheima.stock.controller;
import com.itheima.stock.service.UserService;
import com.itheima.stock.vo.req.LoginReqVo;
import com.itheima.stock.vo.resp.LoginRespVo;
import com.itheima.stock.vo.resp.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
* @author by itheima
* @Date 2021/12/29
* @Description 定义用户访问层
*/
@RestController
@RequestMapping("/api")
public class UserController {
@Autowired
private UserService userService;
/**
* 用户登录功能实现
* @param vo
* @return
*/
@PostMapping("/login")
//@RequestBody将请求中json形式的字符串转换成LoginReqVo对象
public R<LoginRespVo> login(@RequestBody LoginReqVo vo){
R<LoginRespVo> r= this.userService.login(vo);
return r;
}
}
2.3 定义登录服务实现
服务接口:
package com.itheima.stock.service;
import com.itheima.stock.vo.req.LoginReqVo;
import com.itheima.stock.vo.resp.LoginRespVo;
import com.itheima.stock.vo.resp.R;
/**
* @author by itheima
* @Date 2021/12/30
* @Description 用户服务
*/
public interface UserService {
/**
* 用户登录功能实现
* @param vo
* @return
*/
R<LoginRespVo> login(LoginReqVo vo);
}
接口服务实现:
package com.itheima.stock.service.impl;
import com.google.common.base.Strings;
import com.itheima.stock.common.enums.ResponseCode;
import com.itheima.stock.mapper.SysUserMapper;
import com.itheima.stock.pojo.SysUser;
import com.itheima.stock.service.UserService;
import com.itheima.stock.vo.req.LoginReqVo;
import com.itheima.stock.vo.resp.LoginRespVo;
import com.itheima.stock.vo.resp.R;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
/**
* @author by itheima
* @Date 2021/12/30
* @Description 定义服务接口实现
*/
@Service("userService")
public class UserServiceImpl implements UserService {
@Autowired
private SysUserMapper sysUserMapper;
@Autowired
private PasswordEncoder passwordEncoder;
@Override
public R<LoginRespVo> login(LoginReqVo vo) {
if (vo==null || StringUtils.isBlank(vo.getUsername()) || StringUtils.isBlank(vo.getPassword())){
return R.error(ResponseCode.DATA_ERROR.getMessage());
}
//根据用户名查询用户信息
SysUser user=this.sysUserMapper.findByUserName(vo.getUsername());
//判断用户是否存在,存在则密码校验比对
if (user==null || !passwordEncoder.matches(vo.getPassword(),user.getPassword())){
return R.error(ResponseCode.SYSTEM_PASSWORD_ERROR.getMessage());
}
//组装登录成功数据
LoginRespVo respVo = new LoginRespVo();
//属性名称与类型必须相同,否则属性值无法copy
BeanUtils.copyProperties(user,respVo);
return R.ok(respVo);
}
}
2.4 定义mapper方法
在stock_common工程中SysUserMapper下定义接口方法:
/**
* 根据用户名查询用户信息
* @param username
* @return
*/
SysUser findByUserName(@Param("username") String username);
绑定xml:
<select id="findByUserName" resultMap="BaseResultMap">
select <include refid="Base_Column_List"/> from sys_user where
username=#{username}
</select>
2.5 Postman测试
{
"username":"admin",
"password":"123456",
"code": "5566"
}