1.微信小程序登录
1.1小程序登录流程图
1.2使用sa-token完成登录
参考csdn这位老哥的http://t.csdnimg.cn/oRgvI
sa-token是一款轻量级的安全框架
1.2.1首先引入sa-token依赖
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot-starter</artifactId>
<version>1.37.0</version>
</dependency>
1.2.2Controller
@GetMapping("/wxlogin")
@ApiOperation("微信登录")
public Result login(String code) {
//微信登录
UserLoginVo userLoginVo = usersService.wxLogin(code);
return new Result(2000,"登录成功",userLoginVo);
}
1.2.3Service
@Override
@Transactional(rollbackFor = Exception.class)
public UserLoginVo wxLogin(String code) {
//调用微信接口服务,获得当前微信用户的openid
HashMap<String, String> map = new HashMap<>();
//封装参数
map.put("appid",appId);
map.put("secret",secret);
map.put("js_code",code);
map.put("grant_type","authorization_code");
//调用微信接口服务,获得当前微信用户的openid
String json = HttpClientUtil.doGet(WX_LOGIN, map);
//解析json,获得openid
JSONObject jsonObject = JSON.parseObject(json);
System.out.println("111111111111111111111111111111111111111111111");
System.out.println(jsonObject);
System.out.println("111111111111111111111111111111111111111111111");
String openid = jsonObject.getString("openid");
System.out.println(openid);
System.out.println("这是大名鼎鼎的openId******************************************");
//判断openid是否为空,如果为空表示登录失败,抛出业务异常
if(openid == null){
throw new RuntimeException("微信登录失败");
}
//判断当前用户是否为新用户
Users user = usersDao.getByOpenid(openid);
//如果是新用户,自动完成注册
synchronized (this){
if(user == null){
user = Users.builder()
.openid(openid)
.build();
usersDao.insert(user);
}
}
// 使用 Sa-Token 进行登录,并返回Token
StpUtil.login(openid);
String tokenValue = StpUtil.getTokenValue();
System.out.println(tokenValue);
System.out.println("以上是解析*******************************************************");
UserLoginVo build = UserLoginVo.builder()
.openId(openid)
.token(tokenValue)
.build();
//返回这个用户对象
return build;
}
1.2.4返回类
@Builder是创建者模式
@Data
@Builder
public class UserLoginVo implements Serializable {
/**
* 主键ID
*/
private Integer Id;
/**
* 微信服务器上的唯一id
*/
private String openId;
/**
* token
*/
private String token;
}
2.密码加密器
因为PasswordEncoder是springSecurity中的一个模块
2.1引入springSecurity依赖
<!--安全框架 密码加密器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
2.2完成springSecurity安全框架配置
如果不配置的话,它会自动跳入它自定义的用户登录页面
配置密码加密器 再服务层使用
@Configuration
public class MySecurityConfig extends WebSecurityConfigurerAdapter {
// 密码加密器
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().permitAll() // 允许所有请求
.and()
.csrf().disable(); // 禁用 CSRF,可选操作,根据实际需求决定
}
}
2.3controller层
@Api(tags = "后台管理账号密码表控制类(BgManage)")
@RestController
@RequestMapping("bgManage")
public class BgManageController {
/**
* 服务对象
*/
@Resource
private BgManageService bgManageService;
@Resource
private RedisTemplate redisTemplate;
@Resource
private PasswordEncoder passwordEncoder;
@PostMapping("send")
public Result send(@RequestBody LoginFrom loginFrom)
{
String phone = loginFrom.getPhone();
String code = RandomNumUtil.generateVerificationCode();
SendCodeUtils.sendCode(phone,code);
redisTemplate.opsForValue().set(phone,code,10, TimeUnit.MINUTES);
return new Result(2000,"发送验证码成功");
}
@PostMapping("validate")
public ResponseEntity<Result> validate(@RequestBody LoginFrom loginFrom)
{
String phone = loginFrom.getPhone();
String password = loginFrom.getPassword();
String code = loginFrom.getCode();
String o = (String) redisTemplate.opsForValue().get(phone);
System.out.println(o);
BgManage bgManage = bgManageService.queryByPhone(phone);
if (bgManage!=null){
boolean matches = passwordEncoder.matches(password, bgManage.getPassword());
if (matches){
if (code!=null && code.equals(o)){
return ResponseEntity.ok(new Result(2000,"管理员后台登录成功"));
}
else {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new Result(4000, "账号密码或验证码输入不正确"));
}
}
else {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(new Result(4010, "账号密码输入不正确"));
}
}
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new Result(4040, "管理员账号不存在"));
}
/**
* 通过主键查询单条数据
*
* @param phone
* @return 单条数据
*/
@ApiOperation(value = "根据手机号查询 后台管理账号密码表")
@GetMapping("{phone}")
public Result queryByPhone(@ApiParam(value = "后台登录手机号 phone") @PathVariable("phone") String phone) {
return new Result(2000,"根据手机号查询对象成功",bgManageService.queryByPhone(phone)) ;
}
3.post请求为什么会拼接到字符串上
我后端定义的@PostMapping,使用@requestParam 然后 手机号直接拼接在了 url上
前端发送post请求会报错 发送get就可以
然后我在后端修改了 注解 封装成一个 使用@RequestBody注解 解决此问题
4.返回浏览器状态
Response.entity
public ResponseEntity<Result> validate(@RequestBody LoginFrom loginFrom)
{
String phone = loginFrom.getPhone();
String password = loginFrom.getPassword();
String code = loginFrom.getCode();
String o = (String) redisTemplate.opsForValue().get(phone);
System.out.println(o);
BgManage bgManage = bgManageService.queryByPhone(phone);
if (bgManage!=null){
boolean matches = passwordEncoder.matches(password, bgManage.getPassword());
if (matches){
if (code!=null && code.equals(o)){
return ResponseEntity.ok(new Result(2000,"管理员后台登录成功"));
}
else {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new Result(4000, "账号密码或验证码输入不正确"));
}
}
else {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(new Result(4010, "账号密码输入不正确"));
}
}
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new Result(4040, "管理员账号不存在"));
}