前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于若依框架扩展微信扫码登录功能-扫码登录实现

基于若依框架扩展微信扫码登录功能-扫码登录实现

原创
作者头像
薛定喵君
发布2024-10-07 09:02:51
1550
发布2024-10-07 09:02:51
举报
文章被收录于专栏:薛定喵君

前言

上一次我们在若依框架的基础上扩展了微信绑定的功能,下面我们接着来实现扫码登录。

实现思路

PC 端点击微信登录时生成一个 uuid 存入 redis 并弹出一个二维码,二维码地址(附带了生成的 uuid)是移动端的网页,微信扫码后打开的是配置好的网页授权链接,通过网页授权的方式获取 code 拿到用户 openid 后存入redis中,PC 端通过轮询方式根据生成的 uuid 查询用户 openid 进行登录。

实现过程

微信扫码登录

基于以上实现思路结合若依框架需要开发如下几个接口并修改页面:

  • uuid 生成
  • uuid 绑定 openid
  • openid/uuid 登录
  • 登录页追加扫码登录功能
uuid 生成

ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/WxController.java 中追加uuid 生成方法:

代码语言:java
复制
/**
 * 扫码登录用uuid生成
 */
@GetMapping("/uuid/get")
public AjaxResult getUUID() throws IOException
{
    AjaxResult ajax = AjaxResult.success();
    String uuid = IdUtils.simpleUUID();
    String verifyKey = CacheConstants.WX_OPENID_KEY + uuid;
    redisCache.setCacheObject(verifyKey, null, 1, TimeUnit.MINUTES);
    ajax.put("uuid", uuid);
    return ajax;
}

方法里主要利用若依自带的方法生成UUID并存储到redis里(有效期设置为1分钟),需要在 ruoyi-common/src/main/java/com/ruoyi/common/constant/CacheConstants.java 中增加一个 WX_OPENID_KEY 常量用于存放openid:

代码语言:java
复制
/**
 * 微信openid redis key
 */
public static final String WX_OPENID_KEY = "wx_openid:";
uuid 绑定用户openid

同样的,在 WxController.java 中追加uuid绑定用户openid的方法:

代码语言:java
复制
/**
 * uuid绑定openid
 */
@GetMapping("/uuid/bind/openid")
public AjaxResult bindOpenid(@RequestParam("code") String code, @RequestParam("uuid") String uuid) throws IOException
{
    AjaxResult ajax = AjaxResult.success();
    SysUser user = userService.getOpenid(code);
    String openid = user.getOpenid();
    String wxNickName = user.getWxNickName();
    String verifyKey = CacheConstants.WX_OPENID_KEY + uuid;
    long expire = redisCache.getExpire(verifyKey);
    redisCache.setCacheObject(verifyKey, openid);
    if (expire > 0) {
        redisCache.expire(verifyKey, expire, TimeUnit.SECONDS);
    }
    ajax.put("openid", openid);
    ajax.put("wxNickName", wxNickName);
    return ajax;
}

该方法用于微信扫码时接收微信重定向过来的code以及点击扫码登录时产生的随机UUID,调用上一篇SysUserServiceImpl 追加的 getOpenid 方法获取到用户的openid和微信昵称,并把openid更新到对应UUID的redis缓存中。

uuid 登录

WxController.java 中继续追加UUID登录方法:

代码语言:java
复制
/**
 * uuid登录
 */
@GetMapping("/uuid/login")
public AjaxResult loginByOpenId(@RequestParam("uuid") String uuid) throws IOException
{
    AjaxResult ajax = AjaxResult.success();
    String verifyKey = CacheConstants.WX_OPENID_KEY + uuid;
    String openid = redisCache.getCacheObject(verifyKey);
    ajax.put("status", 0);
    System.out.println("openid:{}" + openid);
    if(openid != null) {
        SysUser user = userService.selectUserByOpenId(openid);
        System.out.println("用户:{}" + user);
        if (user == null)
        {
            System.out.println("用户不存在");
            return error("用户不存在");
        }
        LoginUser loginUser = new LoginUser(user.getUserId(), user.getDeptId(), user, permissionService.getMenuPermission(user));
        // 生成token
        String token = tokenService.createToken(loginUser);
        ajax.put("token", token);
        ajax.put("status", 1);
        redisCache.deleteObject(verifyKey);
    }

    return ajax;
}

该方法用于在前端轮询随机生成的UUID,如果在缓存中查询到 openid 就使用 openid 查询用户信息,所以需要在 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java 中补充通过openid查询用户的方法:

代码语言:java
复制
/**
 * 通过openid查询用户
 *
 * @param openId 用户名
 * @return 用户对象信息
 */
@Override
public SysUser selectUserByOpenId(String openId)
{
    return userMapper.selectUserByOpenId(openId);
}

同时要在ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java中追加对应的方法声明:

代码语言:java
复制
/**
 * 通过openId查询用户
 *
 * @param openId openid
 * @return 用户对象信息
 */
public SysUser selectUserByOpenId(String openId);

并且在 ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml 中补充对应的查询sql,根据微信openid获取用户:

代码语言:xml
复制
<select id="selectUserByOpenId" parameterType="String" resultMap="SysUserResult">
	<include refid="selectUserVo"/>
	where u.openid = #{openid} and u.del_flag = '0'
</select>

如果能查询到用户就校验一下用户的权限并生成登录token一起返回给前端。

接口访问权限修改

扫码登录的接口都是在没有登录的时候调用的,所以要在 ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java 中把相关接口加入到允许列表中:

代码语言:java
复制
requests.antMatchers("/login", "/register", "/captchaImage", "/bind-openid", "/uuid/get", "/uuid/login", "/uuid/bind/openid").permitAll()

到这里我们就完成了微信扫码登录所需接口的开发,我们接着来修改页面。

登录页追加微信扫码登录

1.追加接口。在ruoyi-ui/src/api/system/user.js中追加我们上面写好的接口:

代码语言:js
复制
// 查询登录用uuid
export function getLoginUUid() {
    return request({
        url: '/uuid/get',
        method: 'get'
    })
}

// uuid登录
export function uuidLogin(data) {
    return request({
        url: '/uuid/login?uuid=' + data.uuid,
        method: 'get'
    })
}

2.页面修改。修改登录页ruoyi-ui/src/views/login.vue

2.1增加微信登录按钮及弹窗:

代码语言:html
复制
<div class="text-center">
    <img class="mt10 wechat-icon" src="@/assets/images/wx-login.png" alt="微信登录" @click.stop="wxlogin()">
</div>

<el-dialog title="扫码登录" custom-class="bind-dialog" class="new-common-dialog" :visible.sync="bindWxVisible" :close-on-click-modal="false" :close-on-press-escape="false" @close="wxLoginClose" width="320px">
    <div class="qr-code">
        <vue-qr :text="qrUrl" :size="280"></vue-qr>
        <div v-if="bindTimeout" class="tip text-center">
            二维码已失效,请点击
            <i class="el-icon-refresh" @click="wxlogin"></i> 刷新
        </div>
    </div>
</el-dialog>

2.2导入依赖接口及相关方法:

代码语言:js
复制
import {
    getToken
} from "@/utils/auth";
import {
    getLoginUUid,
    getUUid,
    uuidLogin
} from "@/api/system/user";
import vueQr from 'vue-qr'

2.3引用二维码组件:

代码语言:js
复制
components: {
    vueQr,
},

2.4data中新增属性:

代码语言:js
复制
timer: null,
    bindWxVisible: false,
    bindTimeout: false,
    qrUrl: '',

2.5ruoyi-ui/src/store/modules/user.js 文件增加登录缓存方法:

代码语言:js
复制
// uuid登录
uuidLogin({
    commit
}, userInfo) {
    setToken(userInfo.token)
    commit('SET_TOKEN', userInfo.token)
},

2.6登录页增加微信登录相关方法:

代码语言:js
复制
 wxlogin() {
    getLoginUUid().then(response => {
        console.log(response.uuid)
        const uuid = response.uuid
        const redirect_uri = `http://web-hub.uat.kai12.cn/auth.html?backUrl=${本机IP}:8080/uuid/bind/openid?uuid=${uuid}`
        const codeUrl = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=公众号appid&redirect_uri=${encodeURIComponent(redirect_uri)}&response_type=code&scope=snsapi_userinfo&state=123456#wechat_redirect`
        this.qrUrl = codeUrl
        console.log(this.qrUrl)
        this.bindWxVisible = true
        let that = this
        let counter = 1
        this.timer && clearTimeout(this.timer)
        this.timer = setInterval(function() {
            uuidLogin({
                    uuid: uuid
                })
                .then((res) => {
                    console.log(res)
                    counter++
                    console.log(counter)
                    if (counter === 60) {
                        clearTimeout(that.timer)
                        that.bindTimeout = true
                    }
                    if (res.status === 1) {
                        clearTimeout(that.timer)
                        that.bindWxVisible = false
                        that.$message({
                            type: 'success',
                            message: '登录成功',
                        })
                        clearTimeout(that.timer)
                        that.$store.dispatch("uuidLogin", res)
                        setTimeout(() => {
                            that.$router.push({
                                path: that.redirect || "/"
                            }).catch(() => {});
                        }, 1500)
                    }
                })
                .catch((err) => {
                    that.bindWxVisible = false
                    clearTimeout(that.timer)
                })
        }, 1000)
    });
},
wxLoginClose() {
    this.timer && clearTimeout(this.timer)
},

这里主要是通过轮询随机生成的uuid后,手机扫码将code以重定向的方式给到后端的 uuid/bind/openid 接口同时完成UUID传参来实现登录。

然后我们来测试一下:

参考资料

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 实现思路
  • 实现过程
    • 微信扫码登录
      • uuid 生成
      • uuid 绑定用户openid
      • uuid 登录
      • 接口访问权限修改
      • 登录页追加微信扫码登录
  • 参考资料
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档