若依与Uniapp之微信公众号免密登录

1. 微信公众号官网文档

微信公众号官网文档

微信网页开发文档

2. 开发

2.1 后端微信配置

2.1.1 配置微信

#微信公众号配置
wexin:
  #开发者ID
  appid: 保密
  #开发者密码
  secret: 保密
  #获取token的请求地址
  getTokenUrl: https://api.weixin.qq.com/sns/oauth2/access_token

2.1.2 微信公众号接口参数配置

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.chery.common.constant.Constants;
import com.chery.common.utils.http.HttpUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * @description: 调用微信公众号接口参数配置
 * @date 2020-11-27
 */
@Component
@Slf4j
@ConfigurationProperties(prefix = "wexin")
public class EnterpriseWeXin {
    /**
     * 获取token url
     */
    private static String getTokenUrl;

    /**
     * 开发者ID
     */
    private static String appid;
    /**
     * 开发者密码
     */
    private static String secret;


    public static String getGetTokenUrl() {
        return getTokenUrl;
    }

    public void setGetTokenUrl(String getTokenUrl) {
        EnterpriseWeXin.getTokenUrl = getTokenUrl;
    }

    public static String getAppid() {
        return appid;
    }

    public void setAppid(String appid) {
        EnterpriseWeXin.appid = appid;
    }

    public static String getSecret() {
        return secret;
    }

    public void setSecret(String secret) {
        EnterpriseWeXin.secret = secret;
    }

    public static String getOpenId(String code) {
        String openid = "";
        try {
            String param = "appid=" + EnterpriseWeXin.getAppid() + "&secret=" + EnterpriseWeXin.getSecret() + "&code=" + code + "&grant_type=authorization_code";
            String resStr = HttpUtils.sendGet(EnterpriseWeXin.getGetTokenUrl(), param);
            if (StringUtils.isNotEmpty(resStr)) {
                JSONObject res = JSON.parseObject(resStr);
                if (res != null && res.containsKey(Constants.OPENID)) {
                    openid = res.getString(Constants.OPENID);
                }
            }
        } catch (Exception e) {
            log.error("微信公众号获取openid失败", e.getMessage());
        }
        return openid;
    }
}

2.2 免密登录

2.2.1 Uniapp端默认页面bind.vue

<template>
  <view>

  </view>
</template>

<script>
export default {
  onLoad(option) {
    //url提供给微信,然后微信将code传递到该url页面,我这边选的是登录页login.vue
    const url = "http%3A%2F%2Fyuhai.com%2Fpages%2Flogin%2Flogin";
    //发起微信请求,appid参数在公众号获取;scope有两种模式详情见文档
    window.location.href = "https://open.weixin.qq.com/connect/oauth2/authorize?" +
        "appid=wx95a639d8025a505a&redirect_uri=" + url + "&scope=snsapi_base&response_type=code&state=STATE#wechat_redirect";
  },
  methods: {
    toLogin() {
      uni.reLaunch({
        url: '/pages/login/login',
      });
    }
  }
}
</script>

<style>

</style>

踩过的坑:

  1. 回调的url不要带#号,不然回调页面无法获取code
    在这里插入图片描述
  2. 授权后重定向的回调链接地址, 请使用 urlEncode 对链接进行处理
    什么是urlEncode 对链接进行处理?

打开谷歌浏览器的调试控制台
在这里插入图片描述

控制台输入encodeURIComponent(‘url地址’),复制出返回的字符串即可,单引号别复制
在这里插入图片描述

2.2.2 Uniapp端回调login登录页实现免密登录

在这里插入图片描述

onLoad

  onLoad(option) {
    //获取回调code
    this.loginForm.code = option.code;
    //发起code登录
    this.wxLoginByCode()
  }

methods

    wxLoginByCode() {
      //发起微信免密登录
      this.$u.get('/wechat/login?code=' + this.loginForm.code).then(res => {
        if (res.code == 200 && res.token) {
          uni.setStorageSync('token', res.token)
          this.$u.get('/getInfo').then(res => {
            uni.dicParams.user = res.user
            uni.setStorageSync('user', res.user)
            uni.reLaunch({
              url: '/pages/index/index',
            });
          })
        } else {
          uni.showToast({
            icon: 'none',
            title: res.msg,
          });
        }
      }).catch(res => {
        uni.showToast({
          icon: 'none',
          title: res.msg,
        });
      })
    },

2.2.3 后端免密登录接口

    /**
     * 微信免密登录
     *
     * @param code
     * @param state
     * @return
     */
    @GetMapping("/wechat/login")
    public AjaxResult wechatLogin(@RequestParam("code") String code) {
        AjaxResult ajax = AjaxResult.success();
        if (StrUtil.isEmpty(code)) {
            return AjaxResult.error("code不存在");
        }
        // 生成令牌
        String token = loginService.loginWx(code);
        ajax.put(Constants.TOKEN, token);
        return ajax;
    }
    /**
     * 微信免密登录
     *
     * @param code
     * @return
     */
    public String loginWx(String code) {
        String openId = EnterpriseWeXin.getOpenId(code);
        redisCache.setCacheObject(CacheConstants.WEI_XIN_CODE_OPEN_ID_KEY + code, openId, 5, TimeUnit.MINUTES);
        //处理企业微信登录
        LoginUser loginUser = null;
        //校验openId
        SysUser user = userService.getUserByOpenId(openId);
        if (StringUtils.isNotNull(user)) {
            loginUser = new LoginUser(user, permissionService.getMenuPermission(user));
            recordLoginInfo(loginUser.getUser());
            // 生成token
            return tokenService.createToken(loginUser);
        } else {
            throw new ServiceException("未绑定账号,请手动登录!");
        }
    }

2.2.4 踩过的坑

  1. 为什么免密登录获取到openid需要缓存在redis五分钟?
    官网文档:用户同意授权,获取code
    在这里插入图片描述
    如果不缓存并且用户还没绑定到系统,此时用户手动登录时获取不到openid,导致用户系统账号不会和微信openid绑定

  2. 开放匿名微信登录接口

.antMatchers("/wechat/login").permitAll()

不要放在

.antMatchers("/login","/wechat/login", "/captchaImage").anonymous()

2.3 手动登录

用户第一次登录系统,未绑定系统账户时使用的功能
实现用户登录和用户绑定业务需求

2.3.1 Uniapp端login登录页实现手动登录

methods
基本不用动,在请求/login请求时添加code: this.loginForm.code参数

    login() {
      if (this.loginForm.userName == 0) {
        uni.showToast({
          icon: 'none',
          title: '用户名不能为空'
        });
        return;
      }
      if (this.loginForm.password.length == 0) {
        uni.showToast({
          icon: 'none',
          title: '密码不能为空'
        });
        return;
      }
      this.$u.post('/login', {
        username: this.loginForm.userName,
        password: this.loginForm.password,
        code: this.loginForm.code
      }).then(res => {
        if (res.code == 200) {
          if (this.loginForm.rememberPsw) { //用户勾选“记住密码”
            console.log("记住密码")
            uni.setStorageSync('userName', this.loginForm.userName);
            uni.setStorageSync('password', this.loginForm.password);
          } else { //用户没有勾选“记住密码”
            console.log("没有记住密码")
            uni.removeStorageSync('userName');
            uni.removeStorageSync('password');
            this.loginForm.userName = "";
            this.loginForm.password = "";
          }
          uni.setStorageSync('token', res.token)
          this.$u.get('/getInfo').then(res => {
            uni.dicParams.user = res.user
            uni.setStorageSync('user', res.user)
            uni.reLaunch({
              url: '/pages/index/index',
            });
          })
        } else {
          uni.showToast({
            icon: 'none',
            title: res.msg,
          });
        }
      }).catch(res => {
        uni.showToast({
          icon: 'none',
          title: res.msg,
        });
      })
    }

2.3.2 后端login接口

    /**
     * 登录方法
     *
     * @param loginBody 登录信息
     * @return 结果
     */
    @PostMapping("/login")
    public AjaxResult login(@RequestBody LoginBody loginBody) {
        Long userId = null;
        AjaxResult ajax = AjaxResult.success();
        // 生成令牌
        String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getUuid());

        //账号绑定微信openid
        if (StringUtils.isNotEmpty(token) && StringUtils.isNotEmpty(loginBody.getCode())) {
            String code = loginBody.getCode();
            String userName = loginBody.getUsername();
            CompletableFuture.runAsync(() -> {
            	//无法请求微信获取openId,所以从缓存获取
                String openId = redisCache.getCacheObject(CacheConstants.WEI_XIN_CODE_OPEN_ID_KEY + code);
                if (StringUtils.isEmpty(openId)) {
                    log.error("用户: {}绑定微信失败!", userName);
                } else {
                	//根据userName更新openId
                    userService.updateOpenIdByUserName(openId, userName);
                    log.info("用户:{}绑定微信成功!", userName);
                }
            }, threadPoolExecutor);
        }
        
        ajax.put(Constants.TOKEN, token);
        return ajax;
    }

*******************************************************************************************

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
uniapp中,你可以通过使用微信小程序的API来获取微信公众号的code。你可以在前端通过调用小程序的登录接口wx.login()来获取到code,然后将这个code传给后端来获取token。 具体步骤如下: 1. 在前端中,使用wx.login()方法获取到小程序的code。 2. 将获取到的code传给后端,后端通过code调用微信公众号的接口获取到token和openId等用户信息。 参考代码如下: ```javascript // 在uniapp中获取微信公众号的code uni.login({ provider: 'weixin', success: function (loginRes) { if (loginRes.code) { // 将code传给后端 // 调用后端接口获取token和openId等用户信息 } else { console.log('登录失败!' + loginRes.errMsg) } } }) ``` 你可以将上述代码放在需要获取微信公众号code的地方,当用户登录时,调用该代码获取code并传给后端进行处理。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [uniapp微信公众号H5获取code进行登录](https://blog.csdn.net/m0_55333789/article/details/129405206)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [ASP微信公众号授权登陆,获取OpenID,昵称,头像等相关信息完整示例](https://download.csdn.net/download/u010439874/88231886)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

与海boy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值