当前位置: 代码网 > it编程>编程语言>Java > SpringBoot + UniApp对接微信OAuth2登录的全过程

SpringBoot + UniApp对接微信OAuth2登录的全过程

2025年11月30日 Java 我要评论
本文将手把手带你打通springboot后端与uniapp前端的微信登录全流程,并分享那些官方文档没写的实战经验。前期准备在开始编码前,这些准备工作必须到位:微信开放平台账号(个人/企业均可)已审核通

本文将手把手带你打通springboot后端与uniapp前端的微信登录全流程,并分享那些官方文档没写的实战经验。

前期准备

在开始编码前,这些准备工作必须到位

  • 微信开放平台账号(个人/企业均可)
  • 已审核通过的移动应用(审核通常需要1-3个工作日)
  • 获取appid和appsecret(这是微信登录的“身份证”)

特别注意:微信登录权限需要单独申请,通过审核后才能正常使用!

前端实战:uniapp一键登录按钮

关键代码实现

<template>
  <view class="container">
    <button class="wechat-btn" open-type="getuserinfo" @click="handlewechatlogin">
      <uni-icons type="weixin" color="#fff" size="30"></uni-icons>
      微信一键登录
    </button>
  </view>
</template>

<script>
export default {
  methods: {
    async handlewechatlogin() {
      try {
        // 获取微信授权码
        const loginres = await uni.login({
          provider: "weixin",
          onlyauthorize: true, // 关键参数:仅授权不获取用户信息
        });
        
        // 调用后端登录接口
        const res = await uni.request({
          url: "你的后端地址/wechatlogin", // 记得换成你的实际地址!
          method: 'post',
          data: { socialcode: loginres.code }
        });
        
        if (res.data.token) {
          // 登录成功处理
          uni.showtoast({ title: '登录成功!', icon: 'success' });
        } else {
          // 需要绑定手机号
          this.gotobindphone();
        }
      } catch (error) {
        uni.showtoast({ title: '登录失败,请重试', icon: 'none' });
      }
    }
  }
}
</script>

核心要点:

  • onlyauthorize: true 参数确保符合微信规范
  • 异常捕获必不可少,网络请求总有意外
  • token为空时的处理:跳转手机号绑定页面

后端开发:springboot接收与处理

后端的核心使命:安全验证 + 用户管理 + 令牌发放

  • 控制器层
@tag(name = "微信登录")
@restcontroller
public class syslogincontroller {
    
    @autowired
    private sysloginservice loginservice;
    
    @operation(summary = "微信授权登录")
    @postmapping("/wechatlogin")
    public ajaxresult wechatlogin(@requestbody loginbodywechat loginbody) {
        // 三步走:授权 -> 获取用户信息 -> 生成令牌
        map<string, string> authresult = weixinapiservice.authorize(loginbody.getsocialcode());
        map<string, string> userinfo = weixinapiservice.getuserinfo(
            authresult.get("access_token"), 
            authresult.get("openid")
        );
        
        string token = loginservice.wechatlogin(userinfo);
        
        // 返回令牌给前端
        return ajaxresult.success()
            .put(constants.token, token)
            .put("unionid", userinfo.get("unionid"));
    }
}
  • 微信api服务
@component
public class weixinapiservice {
    
    public map<string, string> authorize(string socialcode) {
        string url = string.format(
            "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code", 
            appid, secret, socialcode
        );
        
        string response = httputil.get(url);
        jsonobject jsonobject = jsonutil.parseobj(response);
        
        // 错误处理绝不能少!
        if (jsonobject.containskey("errcode")) {
            throw new serviceexception("微信登录失败:" + jsonobject.get("errmsg"));
        }
        
        // 返回access_token和openid
        return map.of(
            "access_token", jsonobject.getstr("access_token"),
            "openid", jsonobject.getstr("openid")
        );
    }
    public map<string, string> getuserinfo(string accesstoken, string openid) {
        string url = string.format("https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s", 
        accesstoken, openid);
        string response = httputil.get(url);
        jsonobject jsonobject = jsonutil.parseobj(response);
        if (jsonobject.containskey("errcode")) {
            throw new serviceexception("获取微信用户信息失败:" + jsonobject.get("errmsg"));
        }
        map<string, string> result = new hashmap<>();
        result.put("nickname", jsonobject.getstr("nickname"));
        result.put("sex", jsonobject.getstr("sex"));
        result.put("headimgurl", jsonobject.getstr("headimgurl"));
        result.put("unionid", jsonobject.getstr("unionid"));
        result.put("openid", jsonobject.getstr("openid"));
        return result;
    }
}
  • 业务逻辑层:用户存在就登录,不存在就创建
public string wechatlogin(map<string, string> userinfo) {
    // 用unionid查询用户
    sysuser user = userservice.selectuserbyopenid(userinfo.get("unionid"));//这里可以根据自己的业务框架来处理
    
    if (user == null) {
        // 新用户:自动注册
        user = createnewuser(userinfo);
        userservice.insertuser(user);//这里可以根据自己的业务框架来处理
    }
    
    // 未绑定手机号?引导绑定
    if (stringutils.isblank(user.getphonenumber())) {
        return ""; // 前端根据空token跳转绑定页面
    }
    
    // 执行登录,生成token
    return performlogin(user.getphonenumber());//这里可以根据自己的业务框架来处理
}

核心概念解析:openid vs unionid

很多开发者在这里踩坑,其实很简单:

  • openid:用户在单个应用内的身份证(同一个用户在不同应用openid不同)
  • unionid:用户在微信开放平台体系的身份证(同一用户在不同应用unionid相同)

简单理解:openid是部门工号,unionid是公司工号

手机号绑定

重要提醒:微信官方已限制获取用户手机号!我们的解决方案:

  1. 自动检测:用户首次微信登录后,检测是否已绑定手机
  2. 友好引导:token为空时,前端跳转到绑定页面
  3. 简化流程:只需验证码即可完成绑定

参考代码:

@postmapping("/bindphonenumber")
public ajaxresult bindphonenumber(@requestbody loginbodybindphone loginbody) {
    // 验证码校验 + 绑定手机号
    string token = loginservice.bindphonenumber(loginbody);
    return ajaxresult.success().put(constants.token, token);
}
@data
public class loginbodybindphone {

    @schema(description = "手机号")
    private string phonenumber;
    @schema(description = "微信用户统一标识")
    private string unionid;
    @schema(description = "验证码")
    private string code;
}

微信登录对接就像搭积木——步骤固定,但细节决定成败。掌握核心流程(获取code → 换取token → 获取用户信息 → 业务处理),你就能应对各种场景。

总结

到此这篇关于springboot + uniapp对接微信oauth2登录的文章就介绍到这了,更多相关springboot uniapp对接微信oauth2登录内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com