【備戰春招】第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);
}}共同學習,寫下你的評論
評論加載中...
作者其他優質文章

