springboot扫码登录的简单实现

目录
  • 前言
  • 项目简介
  • 实现思路
  • 实现步骤

前言

本文将介绍基于SpringBoot + Vue + Android实现的扫码登录demo的总体思路,完整代码已上传到GitHub。Web端体验地址:http://47.116.72.33/(只剩一个月有效期),apk下载地址:https://github.com/zhangjiwei1221/qrscan/releases/tag/0.0.1。用户名:非空即可,密码:123456,效果见文末,整体实现如有不妥之处,欢迎交流讨论,实现部分参考二维码扫码登录是什么原理。

项目简介

后端:SpringBootRedis
前端:VueVue RouterVueXAxiosvue-qrElemntUI
安卓:ZXingXUIYHttp

实现思路

总体的扫码登录和OAuth2.0的验证逻辑相似,如下所示:

用户选择扫码登录可以看作是A:前端发授权请求,等待app扫码。
用户使用app进行扫码可以看作是B:扫码进行授权,返回一个临时Token供二次认证。
用户在app进行确认登录可以看作是C:进行登录确认,授权用户在Web端登录。
后端在用户确认登录后返回一个正式Token即可看作是步骤D
后续前端根据正式Token访问后台接口,正式在Web端进行操作即可看作是EF

二次认证的原因

之所以在用户扫码之后还需要进行再一次的确认登录,而不是直接就登录的原因,则是为了用户安全考虑,避免用户扫了其他人需要登录的二维码,在未经确认就直接登录了,导致他人可能会在我们不知道的情况下访问我们的信息。

实现步骤

用户访问网页端,选择扫码登录

用户在选择扫码登录时,会向后端发送一个二维码的生成请求,后端生成UUID,并保存到Redis(固定有效时间),状态设置为UNUSED(未使用)状态,如果Redis缓存过期,则为EXPIRE(过期)状态,前端根据后端返回的内容生成二维码,并设置一个定时器,每隔一段时间根据二维码的内容中的UUID,向后端发送请求,获取二维码的状态,更新界面展示的内容。

生成二维码后端接口:

/**
 * 生成二维码内容
 *
 * @return 结果
 */
@GetMapping("/generate")
public BaseResult generate() {
    String code = IdUtil.simpleUUID();
    redisCache.setCacheObject(code, CodeUtils.getUnusedCodeInfo(),
                              DEFAULT_QR_EXPIRE_SECONDS, TimeUnit.SECONDS);
    return BaseResult.success(GENERATE_SUCCESS, code);
}

前端获取内容,生成二维码:

getToken() {
    this.codeStatus = 'EMPTY'
    this.tip = '正在获取登录码,请稍等'
    // 有效时间 60 秒
    this.effectiveSeconds = 60
    clearInterval(this.timer)
    request({
        method: 'get',
        url: '/code/generate'
    }).then((response) => {
        // 请求成功, 设置二维码内容, 并更新相关信息
        this.code = `${HOST}/code/scan?code=${response.data}`
        this.codeStatus = 'UNUSED'
        this.tip = '请使用手机扫码登录'
        this.timer = setInterval(this.getTokenInfo, 2000)
    }).catch(() => {
        this.getToken()
    })
}

后端返回二维码状态信息的接口:

/**
 * 获取二维码状态信息
 *
 * @param code 二维码
 * @return 结果
 */
@GetMapping("/info")
public BaseResult info(String code) {
    CodeVO codeVO = redisCache.getCacheObject(code);
    if (codeVO == null) {
        return BaseResult.success(INVALID_CODE, StringUtils.EMPTY);
    }
    return BaseResult.success(GET_SUCCESS, codeVO);
}

前端轮询获取二维码状态:

getTokenInfo() {
    this.effectiveSeconds--
    // 二维码过期
    if (this.effectiveSeconds <= 0) {
        this.codeStatus = 'EXPIRE'
        this.tip = '二维码已过期,请刷新'
        return
    }
    // 轮询查询二维码状态
    request({
        method: 'get',
        url: '/code/info',
        params: {
            code: this.code.substr(this.code.indexOf('=') + 1)
        }
    }).then(response => {
        const codeVO = response.data
        // 二维码过期
        if (!codeVO || !codeVO.codeStatus) {
            this.codeStatus = 'EXPIRE'
            this.tip = '二维码已过期,请刷新'
            return
        }
        // 二维码状态为为正在登录
        if (codeVO.codeStatus === 'CONFIRMING') {
            this.username = codeVO.username
            this.avatar = codeVO.avatar
            this.codeStatus = 'CONFIRMING'
            this.tip = '扫码成功,请在手机上确认'
            return
        }
        // 二维码状态为确认登录
        if (codeVO.codeStatus === 'CONFIRMED') {
            clearInterval(this.timer)
            const token = codeVO.token
            store.commit('setToken', token)
            this.$router.push('/home')
            Message.success('登录成功')
            return
        }
    })
}

使用手机扫码,二维码状态改变

当用户使用手机扫码时(已登录并且为正确的app,否则扫码会跳转到自定义的宣传页),会更新二维码的状态为CONFIRMING(待确认)状态,并在Redis缓存中新增用户名及头像信息的保存供前端使用展示,此外还会返回用户的登录信息(登录地址、浏览器、操作系统)给app展示,同时生成一个临时Tokenapp(固定有效时间)。

用户扫码时的后台处理:

/**
 * 处理未使用状态的二维码
 *
 * @param code 二维码
 * @param token token
 * @return 结果
 */
private BaseResult handleUnusedQr(String code, String token) {
    // 校验 app 端访问传递的 token
    boolean isLegal = JwtUtils.verify(token);
    if (!isLegal) {
        return BaseResult.error(AUTHENTICATION_FAILED);
    }
    // 保存用户名、头像信息, 供前端展示
    String username = JwtUtils.getUsername(token);
    CodeVO codeVO = CodeUtils.getConfirmingCodeInfo(username, DEFAULT_AVATAR_URL);
    redisCache.setCacheObject(code, codeVO, DEFAULT_QR_EXPIRE_SECONDS, TimeUnit.SECONDS);
    // 返回登录地址、浏览器、操作系统以及一个临时 token 给 app
    String address = HttpUtils.getRealAddressByIp();
    String browser = HttpUtils.getBrowserName();
    String os = HttpUtils.getOsName();
    String tmpToken = JwtUtils.sign(username);
    // 将临时 token 作为键, 用户名为内容存储在 redis 中
    redisCache.setCacheObject(tmpToken, username, DEFAULT_TEMP_TOKEN_EXPIRE_MINUTES, TimeUnit.MINUTES);
    LoginInfoVO loginInfoVO = new LoginInfoVO(address, browser, os, tmpToken);
    return BaseResult.success(SCAN_SUCCESS, loginInfoVO);
}

手机确认登录

当用户在app中点击确认登录时,就会携带生成的临时Token发送更新状态的请求,二维码的状态会被更新为CONFIRMED(已确认登录)状态,同时后端会生成一个正式Token保存在Redis中,前端在轮询更新状态时获取这个Token,然后使用这个Token进行登录。

后端处理确认登录的代码:

/**
 * 处理未待确认状态的二维码
 *
 * @param code 二维码
 * @param token token
 * @return 结果
 */
private BaseResult handleConfirmingQr(String code, String token) {
    // 使用临时 token 获取用户名, 并从 redis 中删除临时 token
    String username = redisCache.getCacheObject(token);
    if (StringUtils.isBlank(username)) {
        return BaseResult.error(AUTHENTICATION_FAILED);
    }
    redisCache.deleteObject(token);
    // 根据用户名生成正式 token并保存在 redis 中供前端使用
    String formalToken = JwtUtils.sign(username);
    CodeVO codeVO = CodeUtils.getConfirmedCodeInfo(username, DEFAULT_AVATAR_URL, formalToken);
    redisCache.setCacheObject(code, codeVO, DEFAULT_QR_EXPIRE_SECONDS, TimeUnit.SECONDS);
    return BaseResult.success(CONFIRM_SUCCESS);
}

效果演示

到此这篇关于springboot扫码登录的简单实现的文章就介绍到这了,更多相关springboot扫码登录内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • springBoot基于webSocket实现扫码登录

    最近单位又有一个新Java项目. 涉及到扫码登录.之前项目使用的是 ajax轮询的方式.感觉太low了. 所以这次用webSocket的方式进行实现 好.废话不多说!咱们开始!! 一.首先咱们需要一张表 这表是干啥的呢? 就是记录一下谁扫码了.谁登录了. User_Token表 字段如下: 1.uuid : 用于确保唯一性 2.userId : 谁登录的 3.loginTime : 登录时间 4.createTime :创建时间 用于判断是否过期 5.state: 是否二维码失效  0有效 1失

  • springboot扫码登录的简单实现

    目录 前言 项目简介 实现思路 实现步骤 前言 本文将介绍基于SpringBoot + Vue + Android实现的扫码登录demo的总体思路,完整代码已上传到GitHub.Web端体验地址:http://47.116.72.33/(只剩一个月有效期),apk下载地址:https://github.com/zhangjiwei1221/qrscan/releases/tag/0.0.1.用户名:非空即可,密码:123456,效果见文末,整体实现如有不妥之处,欢迎交流讨论,实现部分参考二维码扫

  • SpringBoot实现扫码登录的示例代码

    目录 一.首先咱们需要一张表 二.角色都有哪些 三.接口都需要哪些? 四.步骤 五.疯狂贴代码 SpringBoot中操作WebSocket 最近有个项目涉及到websocket实现扫码登录,看到一篇不错的技术文,分享一下. 一.首先咱们需要一张表 这表是干啥的呢?就是记录一下谁扫码了.谁登录了. User_Token表 字段如下: uuid : 用于确保唯一性 userId :谁登录的 loginTime :登录时间 createTime :创建时间 用于判断是否过期 state:是否二维码失

  • SpringBoot实现扫码登录的项目实践

    目录 一.首先咱们需要一张表 二.角色都有哪些 三.接口都需要哪些? 四.步骤 五.疯狂贴代码 Spring Boot中操作WebSocket 一.首先咱们需要一张表 这表是干啥的呢?就是记录一下谁扫码了.谁登录了. User_Token表 字段如下: uuid : 用于确保唯一性 userId :谁登录的 loginTime :登录时间 createTime :创建时间 用于判断是否过期 state:是否二维码失效 0有效 1失效 二.角色都有哪些 咱们还需要分析一下子.扫码登录这个业务逻辑都

  • 详解java实现简单扫码登录功能(模仿微信网页版扫码)

    java实现简单扫码登录功能 模仿微信pc网页版扫码登录 使用js代码生成qrcode二维码减轻服务器压力 js循环请求服务端,判断是否qrcode被扫 二维码超时失效功能 二维码被扫成功登录,服务端产生sessionId,传到页面使用js保存cookie 多线程 生成qrcode相关js jquery.qrcode.js 代码 页面div <div class="pc_qr_code"> <input type="hidden" id="

  • java编程之基于SpringBoot框架实现扫码登录

    目录 项目简介 实现思路 二次认证的原因 实现步骤 用户访问网页端,选择扫码登录 使用手机扫码,二维码状态改变 手机确认登录 效果演示 完整代码已上传到GitHub. Web端体验地址:http://47.116.72.33/(只剩一个月有效期) apk下载地址:https://github.com/zhangjiwei1221/qrscan/releases/tag/0.0.1. 用户名:非空即可,密码:123456,效果见文末,整体实现如有不妥之处,欢迎交流讨论 实现部分参考二维码扫码登录是

  • 基于 Swoole 的微信扫码登录功能实现代码

    随着微信的普及,扫码登录方式越来越被现在的应用所使用.它因为不用去记住密码,只要有微信号即可方便快捷登录.微信的开放平台原生就有支持扫码登录的功能,不过大部分人还是在用公众平台,所以扫码登录只能自行实现.这里基于微信公众平台的带参数临时二维码,并且结合 Swoole 的 WebSocket 服务实现扫码登录.大体流程如下: 客户端打开登录界面,连接到 WebSocket 服务 WebScoket 服务生成带参数二维码返回给客户端 用户扫描展示的带参数二维码 微信服务器回调扫码事件并通知开发者服务

  • javaweb实现app扫码登录功能

    本文为大家分享了javaweb实现app扫码登录的具体代码,供大家参考,具体内容如下 1.web页面主动向服务器索要一张由服务器生成包含维一标识的二维码图片,也可以直接向后台索要一个维一标识,拿到标识后通过js生成二维码.这里本人采用的是第二种方式,至于为什么吗?个人感觉这样方便,后台也不要导入架包,最后将该标识存入List集合中,接下来会用到该标识 2.app扫码后解析二维码内的维一标识,然后再携带该标识跟用户名发回给服务器,服务器接到请求后,遍历List集合,验证该标识是否为本系统生成的,若

  • Java Spring Boot实现简易扫码登录详解

    目录 前言 项目简介 实现思路 实现步骤 1.用户访问网页端,选择扫码登录 2.使用手机扫码,二维码状态改变 3.手机确认登录 效果演示 总结 前言 本文将介绍基于SpringBoot + Vue + Android实现的扫码登录demo的总体思路,完整代码已上传到GitHub.Web端体验地址:http://47.116.72.33/(只剩一个月有效期),apk下载地址:https://github.com/Zjvngvn/qrscan/releases/tag/0.0.1.用户名:非空即可,

  • 浅谈js二维码扫码登录是什么原理

    目录 二维码登录的本质 认识二维码 系统认证机制 扫描二维码登录的一般步骤 大概流程 二维码准备 扫描状态切换 状态确认 总结 前几天看了极客时间一个二维码的视频,写的不错,这里总结下 在日常生活中,二维码出现在很多场景,比如超市支付.系统登录.应用下载等等.了解二维码的原理,可以为技术人员在技术选型时提供新的思路.对于非技术人员呢,除了解惑,还可以引导他更好地辨别生活中遇到的各种二维码,防止上当受骗. 二维码,大家再熟悉不过了 购物扫个码,吃饭扫个码,坐公交也扫个码 在扫码的过程中,大家可能会

随机推荐