【备战春招】第14天 扫码登录
课程名称:在线办公系统
课程章节: 第1章
课程讲师:神思者
课程内容
登录页面 点击切换时 从输入框切换到二维码登录
在UserService.java
接口中定义生成二维码的抽象方法。
public interface UserService { public HashMap createQrCode(); }
在UserServiceImpl.java
类中实现抽象方法
@Servicepublic class UserServiceImpl implements UserService { @Autowired private RedisTemplate redisTemplate; …… @Override public HashMap createQrCode() { String uuid = IdUtil.simpleUUID(); //key是uuid,value的false代表该uuid没有被使用,防止该二维码被重复扫码 redisTemplate.opsForValue().set(uuid, false, 5, TimeUnit.MINUTES); //设置二维码信息 QrConfig config = new QrConfig(); config.setHeight(160); config.setWidth(160); config.setMargin(1); //把生成的二维码图片转换成base64字符串 String base64 = QrCodeUtil.generateAsBase64("login@@@" + uuid, config, ImgUtil.IMAGE_TYPE_JPG); HashMap map = new HashMap() {{ put("uuid", uuid); put("pic", base64); }}; return map; }}
将uuid作为key存入redis 当value是false时 代表二维码未使用
在UserController.java
类中定义Web方法,并且用Swagger测试该Web方法。
@RestController @RequestMapping("/user") @Tag(name = "UserController", description = "用户Web接口") public class UserController { /** * 生成登陆二维码的字符串 */ @GetMapping("/createQrCode") @Operation(summary = "生成二维码Base64格式的字符串") public R createQrCode() { HashMap map = userService.createQrCode(); return R.ok(map); }}
用户在微信上面扫描了二维码之后,会调用后端Web方法,修改Redis里面缓存UUID对应的VALUE值,如果false变成了userId,说明用户已经在微信上扫码成功了。我们要接收微信小程序提交过来的Ajax请求,里面就包括了用户的临时授权code字符串,经过转换之后我们拿到openId字符串。因为每个用户的openId字符串都是唯一的,所以我们可以根据openId字符串作为查询条件,查询userId。如果存在userId,就可以判定该用户登陆,我们把userId写入Redis。然后浏览器端不停地轮询Redis,如果发现UUID对应的Value已经变成了userId,这时候就认为用户登陆成功,颁发Token令牌即可。
在TbUserDao.xml
文件中定义SQL语句,根据OpenId查询用户的UserId。
<select id="searchIdByOpenId" parameterType="String" resultType="Integer"> SELECT id FROM tb_user WHERE open_id=#{openId} AND status = 1 </select>
在TbUserDao.java
接口中声明抽象DAO方法。
@Mapperpublic interface TbUserDao { public Integer searchIdByOpenId(String openId); }
在UserService.java
接口中定义抽象方法。
public interface UserService { public boolean checkQrCode(String code, String uuid); }
在UserServiceImpl.java
类中实现抽象方法。
@Servicepublic class UserServiceImpl implements UserService { @Value("${wx.app-id}") private String appId; @Value("${wx.app-secret}") private String appSecret; …… @Override public boolean checkQrCode(String code, String uuid) { boolean bool = redisTemplate.hasKey(uuid); if (bool) { String openId = getOpenId(code); Integer userId = userDao.searchIdByOpenId(openId); redisTemplate.opsForValue().set(uuid, userId); if (userId != null && userId > 0) { return true; } } return false; } //用于把Code临时授权转换成OpenID private String getOpenId(String code) { String url = "https://api.weixin.qq.com/sns/jscode2session"; HashMap map = new HashMap(); map.put("appid", appId); map.put("secret", appSecret); map.put("js_code", code); map.put("grant_type", "authorization_code"); String response = HttpUtil.post(url, map); JSONObject json = JSONUtil.parseObj(response); String openId = json.getStr("openid"); if (openId == null || openId.length() == 0) { throw new RuntimeException("临时登陆凭证错误"); } return openId; }}
这里的code 是需要用到wx.login 返回得 code
创建CheckQrCodeForm.java
类,封装微信小程序Ajax提交的请求。
@Data@Schema(description = "检验登陆验证码表单")public class CheckQrCodeForm { @NotBlank(message = "uuid不能为空") @Schema(description = "uuid") private String uuid; @NotBlank(message = "临时授权不能为空") @Schema(description = "临时授权") private String code;}
在UserController.java
类中
@RestController @RequestMapping("/user") @Tag(name = "UserController", description = "用户Web接口") public class UserController { @PostMapping("/checkQrCode") @Operation(summary = "检测登陆验证码") public R checkQrCode(@Valid @RequestBody CheckQrCodeForm form) { boolean bool = userService.checkQrCode(form.getCode(), form.getUuid()); return R.ok().put("result", bool); }}
共同学习,写下你的评论
评论加载中...
作者其他优质文章