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) {//调用微信接口服务,获得当前微信用户的openidHashMap<String, String> map = new HashMap<>();//封装参数map.put("appid",appId);map.put("secret",secret);map.put("js_code",code);map.put("grant_type","authorization_code");//调用微信接口服务,获得当前微信用户的openidString json = HttpClientUtil.doGet(WX_LOGIN, map);//解析json,获得openidJSONObject 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 进行登录,并返回TokenStpUtil.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 {// 密码加密器@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}@Overrideprotected 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 {/*** 服务对象*/@Resourceprivate BgManageService bgManageService;@Resourceprivate RedisTemplate redisTemplate;@Resourceprivate 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, "管理员账号不存在"));}