为了账号安全,请及时绑定邮箱和手机立即绑定

【备战春招】第14天 扫码登录

标签:
SpringBoot

课程名称:在线办公系统


课程章节: 第1章


课程讲师:神思者


课程内容



https://img1.sycdn.imooc.com//63f417d80001f81f04350209.jpg


登录页面 点击切换时 从输入框切换到二维码登录

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);
    }}




https://img1.sycdn.imooc.com//63f41ad6000184e511310619.jpg








点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
Web前端工程师
手记
粉丝
25
获赞与收藏
19

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消