java扫码登入

2 篇文章 0 订阅
1 篇文章 0 订阅

使用工具:redis+qrcode.js+jquery.js

注意事项:扫码手机必须跟项目使用同一网络ip;不然网络ip不同扫码请求访问不到项目服务,

我这里是用手机连接电脑热点进行扫码;亲测!!!

整体实现描述

前端生成二维码后,同时发起频繁请求来判断二维码的登入状态,用户扫码进行登入后,后端验证登入通过后,把二维码登入状态存入redis,前端接收到成功登入返回值后进行页面跳转。

1.前端登入页面生成二维码

扫码页面定义一个div容器用来存放生成的二维码,当点击扫码登入的时候使用单机事件,触发一个生成二维码的函数,函数执行qrcode.js的new QRCode(“放二维码的容器”,”二维码内容”)方法来生成一个二维码,二维码内容写入需要访问登入页面的url。同时使用js的setInterval(“执行的方法或代码”,”每隔多少毫秒执行”)方法生成一个定时器,开启定时器用来判断二维码的登入状态,因为考虑到二维码的唯一性,所以需要给二维码设置一个唯一标识,我们可以使用一个Math.random()的随机数方法加上一个当前时间的时间戳,组合成一个字符串,代表二维码的唯一标识,用来保证每二维码标识的唯一性,把二维码的唯一标识拼接到二维码登入页面的url中,让扫码后登入页面的登入请求使用。

2.前端扫码后登入页面的登入请求

当我们扫码页面生成二维码之后我们就可以进行扫码登入了,扫描二维码进入到登入页面,因为二维码的唯一性,所以我们要携带着二维码的唯一标识来进行登入请求。因为我们把二维码的唯一标识已经放入二维码的访问url中了,所以我们可以直接获取二维码唯一标识,这里使用window对象的localtion.search的方法来获取请求路径中从问号(?)开始的url路径,也就是我们请求中拼接的二维码唯一标识,截取后获取二维码的唯一标识,发送一个登入请求携带着我们的二维码唯一标识,让后端用来存储二维码的登入状态。

3.后端二维码登入请求的处理

我们后端API接口收到带着二维码标识的登入请求后,就可以进行登入的业务处理了,首先需要验证账号密码是否正确,如果有误直接返回账号或密码验证失败。当账号密码都验证通过后我们对二维码进行处理,我们可以使用redis来存储一个token,用来验证前端登入请求是否登入成功,同时也是用户登入后的token凭证,Key就是二维码的唯一标识,因为是唯一的标识,所以不会造成不同的二维码登入冲突。存储token后就可以返回登入成功的请求了,来告诉扫码页面已经扫码登入成功了。

4.定时器获取后端二维码的登入状态

我们第一步生成二维码的时候,同时也开启了一个定时器,我们要使用定时器来获取二维码的登入状态,使用定时器调用一个函数,不断发送一个查看二维码登入状态的请求,设置好定时器时间每隔多少毫秒发送请求,因为我们生成的二维码是唯一性的,所以判断二维码登入状态,需要拿着二维码的唯一标识来进行后端的判断,后端收到定时器频繁发来的请求后,进行判断用户是否完成扫码登入,具体实现就是拿着二维码的唯一标识,查询redis是否存有成功登入后存储的token,如果有token证明扫码页面用户已经登入成功了,就可以返回登入成功状态与token凭证到前端了,让前端做出登入成功后的响应与处理。

5.前端登入成功后的响应与处理

前端定时器执行判断登入状态的请求,一旦接收到后端返回成功登入装态的返回值,就可以进行成功登入的响应处理了,首先获取成功登入的token凭证,使用SessionStore.setItem(“键”,”值”)方法把凭证存储到sessionStore中,让登入后的其他请求使用,使用 定时器.close()方法把判断登入状态的定时器关闭,最后进行登入成功后的页面跳转即可。完成扫码登入!!!

 实现代码

1.前端生成二维码并开启定时器:

        //生成二维码函数
        function getQRCode() {
            //随机数+时间戳生成一个二维码唯一标识
            var qrCode = Math.random().toString().substring(2) + new Date().getTime();
            //生成二维码,第一个参数是放二维码的容器,第二个参数是二维码访问地址
            new QRCode(document.getElementById("QRCodeDiv"), "http://192.168.1.113:2222/tm-shop-show/shop-front-end/QRCode.html?QRCode=" + qrCode);
            //创建一个定时器执行函数获取二维码登入状态
            var interval = setInterval(getQRCodeStatus, 1000);
            //定时器函数获取二维码登入状态
            function getQRCodeStatus() {
                $.ajax({
                    url: "http://localhost:7777/user/user/getQRCodeStatus",
                    type: "post",            
                    data: {"qrCode": qrCode},
                    dataType: "json",
                    success: function (result) {
                        if (result.code === 200) {
                            //登入成功把token存入sessionStore中
                            sessionStorage.setItem("token", result.result);
                            //跳转页面
                            $(location).attr("href", "index.html");
                            //关闭定时器
                            clearInterval(interval);
                        }
                    },
                    error: function () {
                        alert("获取登入状态失败");
                    }
                })
            }
        }

2.扫码后登入页面的登入请求:

//登入函数
function userLogin() {
            var search = window.location.search; //获取请求路径?后字符串
            var QRCode = search.substring(8)  //截取二维码唯一标识
            var inputName = $("#inputName").val()
            var inputPassword = $("#inputPassword").val()
            //发送登入请求
            $.ajax({
                url: "http://192.168.1.113:7777/user/user/userLogin",
                type: "post",
                data: {"inputName": inputName, "inputPassword": inputPassword,"QRCode":QRCode},
                dataType: "json",
                success: function (result) {
                    if(result.code == 200){
                        alert("登入成功")
                        //登入成功后关闭页面
                        window.close();
                    }
                },
                error: function () {
                    alert("登入失败")
                }
            })
        }

3.后端验证登入状态:

/**
     * @title user
     * @author lixiang
     * @updateTime 2021/11/17 15:14
     * @description :用户登入
     */
    @Override
    public RestReturnModel userLogin(LoginUserEntity loginUserEntity) {
        //获取用户账号密码
        UserEntity user = userMapper.getUser(loginUserEntity.getInputName());
        if (null == user) {
            //如果账号不存在返回账号不存在
            return RestReturnModel.LOGIN_ERROR("账户不存在");
        }
        if (MD5Util.valid(loginUserEntity.getInputPassword(), MD5Util.MD5Upper("password", user.getPassword()))
        ) {
            //如果密码不正确返回密码不正确
            return RestReturnModel.LOGIN_ERROR("密码错误");
        }
        //生成token凭证
        String token = JwtTokenUtil.generateToken(user);
        if (null != loginUserEntity.getQRCode()) {
            //如果是二维码登入存入的key为二维码唯一标识
            redisTemplate.opsForValue().set(loginUserEntity.getQRCode(), token, 30, TimeUnit.MINUTES);
            //返回登入成功
            return RestReturnModel.LOGIN_SUCCESS(token);
        }
        //非二维码登入把token存入到redis
        redisTemplate.opsForValue().set("token_" + user.getUsername(), token, 30, TimeUnit.MINUTES);
        //返回登入成功
        return RestReturnModel.LOGIN_SUCCESS(token);
    }

4.后端接收定时器请求返回登入状态:

/**
     * @title user
     * @author lixiang
     * @updateTime 2021/11/19 21:02
     * @description :返回二维码登入状态
     */
    @Override
    public RestReturnModel getQRCodeStatus(String qrCode) {
        //拿着二维码唯一标识获取redis中二维码状态
        String token = (String) redisTemplate.opsForValue().get(qrCode);
        //如果不为空则代表二维码登入成功了
        if(null != token){
            //返回成功登入状态
            return RestReturnModel.LOGIN_SUCCESS(token);
        }
        //为空则代表二维码还未登入成功
        return RestReturnModel.LOGIN_ERROR("暂未登入");
    }

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值