PC端扫描小程序二维码登录

54 篇文章 0 订阅

maven pom.xml文件添加依赖

       <dependency>
                <groupId>com.github.binarywang</groupId>
                <artifactId>weixin-java-miniapp</artifactId>
                <version>4.4.8.B</version>
            </dependency>

微信小程序配置:

#环境配置文件配置小程序APPID和密钥
wx:
    app-id: xx
    app-secret: xx


#获取配置环境的属性值
package com.xx.framework.config.properties;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

/**
 * 微信参数
 */
@Configuration
@ConfigurationProperties(prefix = "wx")
@Data
public class WxProperties {
    private String appId;
    private String appSecret;
}

#配置微信小程序类
package com.xx.framework.config;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
import cn.binarywang.wx.miniapp.config.WxMaConfig;
import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
import com.xx.framework.config.properties.WxProperties;
import lombok.AllArgsConstructor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@AllArgsConstructor
@Configuration
public class WxConfig {
    private final WxProperties wxProperties;
    /**
     * 小程序配置
     * @return
     */
    @Bean
    @ConditionalOnMissingBean
    public WxMaConfig wxMaConfig() {
        WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl();
        config.setAppid(this.wxProperties.getAppId());
        config.setSecret(this.wxProperties.getAppSecret());
        return config;
    }

    @Bean
    public WxMaService wxMaService(WxMaConfig maConfig) {
        WxMaService service = new WxMaServiceImpl();
        service.setWxMaConfig(maConfig);
        return service;
    }
}

1、获取二维码地址,通过请求微信开发者文档中的服务端获取无限制小程序二维码URL

#controller层
import org.apache.commons.codec.binary.Base64;
 /**
     * 获取小程序二维码
     */
    @PassToken
    @GetMapping("/getQrCode")
    public AjaxResult getQrCode(BlogUserDto blogUserDto){
        String base64 = blogUserService.getQrCode(blogUserDto);
        if (StrUtil.isBlank(base64)){
            return AjaxResult.error("获取二维码失败");
        }
        return AjaxResult.success("data:image/png;base64,"+base64);
    }

#service层

    /**
     * 获取小程序二维码
     * @return
     */
    String getQrCode(BlogUserDto blogUserDto);


#service impl层
@Override
    public String getQrCode(BlogUserDto blogUserDto) {
        String base64;
        try{
            //先判断access_token是否存在。不存在则查询
            String key = Constants.MINAPP_ACCESS_TOKEN;
            String accessToken = null;
            if (redisCache.hasKey(key)){
                accessToken = redisCache.getCacheObject(key);
            }
            if (accessToken  == null){
                accessToken = wxMaService.getAccessToken(true);
                redisCache.setCacheObject(key,accessToken,7200, TimeUnit.SECONDS);
            }
            //传入的参数a=1&b=2
            String scene = blogUserDto.getScene();
            //扫码后跳转的页面
            String page = "pages/index";
            boolean checkPath = false;
            //版本。正式版为release,体验版trial,开发版develop
            String envVersion = "develop";
            //二维码的宽度
            int width = 280;
            boolean autoColor= false;
            WxMaCodeLineColor lineColor = null;
            boolean isHyaline = false;
            //获取无限制二维码
            byte[] bytes = wxMaService.getQrcodeService().createWxaCodeUnlimitBytes(scene,page,checkPath,envVersion,width,autoColor,lineColor,
                    isHyaline);
            base64 = new String(Objects.requireNonNull(Base64.encodeBase64(bytes)));
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
        return base64;
    }

#Constant类
    /**
     * 小程序access_token
     */
    public static final String MINAPP_ACCESS_TOKEN = "minapp_access_token:";

2、将获取到的base64图片地址显示在PC端

<div  style="width: 100%;height: 100%;text-align: center;position:relative">
                <img :src="codeUrl" alt=""  :loading="loadingCorUrl"
                 style="">
                <div v-if="showexpire"  @click="clickScanQR" style="width: 65%;height: 98%;
                position:absolute;top:0%;left:50%;
                transform:translateX(-50%);opacity: 0.9;font-size:20px;
                background-color: darkgray;font-color:black;">
                  <div style="position:absolute;top:40%;left:40%;">
                    <i class="el-icon-refresh" style="font-size:60px;color:#ffffff;cursor: pointer;"></i>
                  </div>
                  <div style="position:absolute;top:65%;left:25%;font-size:15px;color:#ffffff;">
                    二维码失效,点击重试</div>
                </div>
              </div>



      scene:null,
      timer:null,
      loadingCorUrl:false,
      showexpire:false,



 //点击重新刷新二维码
    clickScanQR(){
      this.getQrCode();
    },

3、scene的值由PC端生成传给获取二维码的接口。

4、uniapp收到scene的值后,小程序微信登录

 onLoad: function(query) {
		this.getBanner();
		// this.getBlogList();
		setTimeout(function () {
			console.log('start pulldown');
		}, 1000);
		uni.startPullDownRefresh();
		//获取pc端扫码后传的参数值
		const scene = decodeURIComponent(query.scene);
		console.log("scene:"+scene);
		//如果scene有值,判断用户是否登录
		if(scene && scene != undefined && scene != 'undefined'){
			console.log("token:"+this.$store.state.user.token)
			//如果登录,授权网站。
			if(this.$store.state.user.token){
				console.log("llll")
				updateScene({"scene":scene}).then(res=>{
					
				});
			}else{
				// 如果没有登录,直接微信登录,授权网站
				this.$tab.navigateTo('/pages/mine/wxlogin/index?scene='+scene)
			}
		}
	},

5、pc端具体代码

algorithm(){
    		let abc=['a','b','c','d','e','f','g','h','i','g','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'];
    		let [max,min]=[Math.floor(Math.random()*(10-7+1)+1),Math.floor(Math.random()*(17-10+1)+17)];
    		abc=abc.sort(()=>0.4-Math.random()).slice(max,min).slice(0,8).join("");
    		var a=new Date().getTime()+abc;
    		return a
    },

getQrCode(){
      this.scene = this.algorithm();
      this.loadingCorUrl=true;
      this.showexpire=false;
      getQrCode({"scene":this.scene}).then(res=>{
        if(res.code == 200){
          this.codeUrl=res.msg;
          if(this.codeUrl && this.codeUrl != undefined && this.codeUrl != 'undefined'){
              this.loadingCorUrl=false;
              //获取后轮询
              var _this = this;
              var seconds=0,minutes=0;
              _this.timer = setInterval(()=>{
                seconds=seconds+3;
                console.log("seconds:"+seconds);
                if(seconds == 60){
                  minutes = minutes+1;
                }
                _this.$store.dispatch("BlogLoginByScene", {"scene":_this.scene}).then((res) => {
                  if(res.code == 200 && res.token && res.token != undefined &&  res.token != 'undefined'){
                    clearInterval(_this.timer);
                    _this.open = false;
                    _this.getUserInfo();
                  }
                }).catch(() => {
                });
                console.log("minutes:"+minutes)
                if(minutes == 1){
                  clearInterval(_this.timer);
                  _this.showexpire=true;
                }
              },3000)
          }
        }
      })
    },

6、第5条里的微信扫码登录是另外的接口,在登录配置里另外配置,设置如下

#store->userBlog.js里设置
import {login, logout, getInfo,loginByScene} from '@/api/loginBlog'
 //根据scene查询登录
    BlogLoginByScene({commit}, userInfo) {
      const scene = userInfo.scene
      return new Promise((resolve, reject) => {
        loginByScene(scene).then(res => {
          if(res.code == 200 && res.token && res.token != undefined  && res.token != 'undefined'){
            setToken(res.token)
            commit('SET_BLOG_TOKEN', res.token)
          }
          resolve(res)
        }).catch(error => {
          reject(error)
        })
      })
    },

#api->loginBlog.js
//根据scene查询登录
export function loginByScene(scene) {
  const data = {
    scene
  }
  return request({
    url: '/reception/blog/user/getUserByScene',
    headers: {
      isToken: false
    },
    method: 'get',
    params: data
  })
}

7、后端接口

#controller层
/**
     * 根据scene查询用户
     */
    @PassToken
    @GetMapping("/getUserByScene")
    public AjaxResult getUserByScene(BlogUserDto blogUserDto){
        if (StrUtil.isBlank(blogUserDto.getScene())){
            return AjaxResult.error("参数值错误");
        }
        BlogUser blogUser = blogUserService.getOne(new LambdaQueryWrapper<BlogUser>()
                .select(BlogUser::getId)
        .eq(BlogUser::getScene,blogUserDto.getScene()));
        if (blogUser != null){
            //创建token
            Map<String,Object> claims = new HashMap<>();
            claims.put("uuid", IdUtils.getLongId());
            claims.put(Constants.BLOG_LOGIN_USER_KEY,blogUser.getId());
            String token = tokenService.createToken((claims));

            redisCache.setCacheObject(CacheConstants.BLOG_LOGIN_TOKEN_KEY + blogUser.getId(),token);
            AjaxResult ajax = AjaxResult.success();
            ajax.put(Constants.TOKEN, token);
            return ajax;
        }
        return AjaxResult.success();
    }

    /**
     * 更新用户scene值
     * @param id
     * @param blogUser
     * @return
     */
    @PutMapping("/updateScene")
    public AjaxResult updateScene(@CurrentUser Long id,@RequestBody BlogUser blogUser){
        blogUser.setId(id);
        blogUserService.updateById(blogUser);
        return AjaxResult.success();
    }

注释:

如果获取accesstoken出现以下错误,请获取稳定版本

{"errcode":40001,"errmsg":"invalid credential, access_token is invalid or not latest, could get access_token by getStableAccessToken, more details at https://mmbizurl.cn/s/JtxxFh33r rid: 65b3294e-6993fa45-745b3def"}
结果:{"errcode":40001,"errmsg":"invalid credential, access_token is invalid or not latest, could get access_token by getStableAccessToken, more details at https://mmbizurl.cn/s/JtxxFh33r rid: 65b3294e-6993fa45-745b3def"}
 

获取稳定版接口调用凭据 | 微信开放文档

POST https://api.weixin.qq.com/cgi-bin/stable_token
  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

飞流银河

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

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

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

打赏作者

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

抵扣说明:

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

余额充值