网站应用实现微信扫码登录完整示例

news/2024/7/20 2:31:57 标签: 微信, 小程序, 微信小程序

网站应用实现微信扫码登录完整示例

  • 阅读文档
  • 微信参数配置
  • 生成二维码
    • 1.跳转新窗口二维码登录
    • 2.网站内嵌二维码微信登录
  • 封装二维码参数接口
  • 微信回调接口
  • 回调返回页面

阅读文档

https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Wechat_Login.html

微信参数配置

wx:
  open:
    app_id: wxedaaaaaaaa89b47
    app_secret: 23wxedaaaaaaaa89b475155
    redirect_url: http://localhost:8888/api/wx/callback
@Component
public class WxConfig implements InitializingBean {

    @Value("${wx.open.app_id}")
    private String appId;

    @Value("${wx.open.app_secret}")
    private String appSecret;

    @Value("${wx.open.redirect_url}")
    private String redirectUrl;

    public static String WX_OPEN_APP_ID;
    public static String WX_OPEN_APP_SECRET;
    public static String WX_OPEN_REDIRECT_URL;

    @Override
    public void afterPropertiesSet() {
        WX_OPEN_APP_ID = appId;
        WX_OPEN_APP_SECRET = appSecret;
        WX_OPEN_REDIRECT_URL = redirectUrl;
    }
}

生成二维码

1.跳转新窗口二维码登录

通过网站点击事件跳转新窗口二维码登录

https://open.weixin.qq.com/connect/qrconnect?appid=xxxxxx&redirect_uri=http%3A%2F%2Flocalhost%3A8888%2Fapi%2Fwx%2Fcallback&response_type=code&scope=snsapi_login&state=3d6be0a4035d839573b04816624a415e#wechat_redirect

2.网站内嵌二维码微信登录

<template>
  <div>
    <el-button @click="login">登录</el-button>

    <div id="weixinLogin" style="width: 200px;height: 200px"></div>
  </div>
</template>

<script>
import demoApi from "@/api/demodemoApi";

export default {
  data() {
    return {}
  },
  mounted() {
    const script = document.createElement('script')
    script.type = 'text/javascript'
    script.src = 'http://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js'
    document.body.appendChild(script)
  },
  methods: {
    login() {
      demoApi.getLoginParam().then(response => {
        var obj = new WxLogin({
          self_redirect: true,
          id: 'weixinLogin',
          appid: response.data.appid,
          scope: response.data.scope,
          redirect_uri: response.data.redirect_uri,
          state: response.data.state,
          style: 'black',
          href: ''
        })
        console.log(obj)
      })
    }
  }
}
</script>

<style scoped>

</style>

demoApi.js

import request from '@/utils/request'
export default {
   getLoginParam() {
    return request({
      url: 'http://localhost:8888/api/wx/getLoginParam',
      method: 'get'
    })
  }
}

封装二维码参数接口

    @GetMapping("getLoginParam")
    @ResponseBody
    public Map<String, Object> genQrConnect() {
        try {
            Map<String, Object> map = new HashMap<>();
            map.put("appid", WxConfig.WX_OPEN_APP_ID);
            map.put("scope","snsapi_login");
            String wxOpenRedirectUrl = WxConfig.WX_OPEN_REDIRECT_URL;
            wxOpenRedirectUrl = URLEncoder.encode(wxOpenRedirectUrl, "utf-8");
            map.put("redirect_uri",wxOpenRedirectUrl);
            map.put("state",System.currentTimeMillis()+"");
            return map;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return null;
        }
    }

微信回调接口

    @GetMapping("callback")
    public String callback(String code, String state) {
        //获取临时票据 code
        log.info("code:{}", code);

        // 组装获取accessToken的url
        String accessTokenUrl = getAccessTokenUrl(code);

        // httpclient请求获取accesstokenInfo
        try {
            String accesstokenInfo = HttpClientUtils.get(accessTokenUrl);
            log.info("accesstokenInfo:{}", accesstokenInfo);

            //从返回字符串获取两个值 openid和access_token
            JSONObject jsonObject = JSONObject.parseObject(accesstokenInfo);
            String access_token = jsonObject.getString("access_token");
            String openid = jsonObject.getString("openid");

            // TODO 根据openid判断数据库是否存在微信用户信息
            UserInfo userInfo = null;
            if (userInfo == null) {
                // httpclient请求获取用户信息
                String userInfoUrl = getUserInfoUrl(access_token, openid);
                String resultInfo = HttpClientUtils.get(userInfoUrl);
                log.info("resultInfo:{}", resultInfo);

                //解析用户信息
                JSONObject resultUserInfoJson = JSONObject.parseObject(resultInfo);
                //用户昵称
                String nickname = resultUserInfoJson.getString("nickname");
                //用户头像
                String headimgurl = resultUserInfoJson.getString("headimgurl");

                // TODO 微信用户信息保存数据库
            }

            // 数据库存在微信用户信息,生产Token信息后直接返回
            Map<String, String> map = new HashMap<>();
            map.put("name", "userName");
            map.put("token", "createTwtToken");

            //跳转前端页面
            return "redirect:" + "http://localhost:9528" + "/weixin/callback?token=" + map.get("token") + "&name=" + URLEncoder.encode(map.get("name"), "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
            log.error("httpclient请求出现异常。。。");
            return null;
        }
    }

    /**
     * 使用code、appid、appscrect换取access_token
     *
     * @param code
     * @return
     */
    private String getAccessTokenUrl(String code) {
        StringBuffer baseAccessTokenUrl = new StringBuffer()
                .append("https://api.weixin.qq.com/sns/oauth2/access_token")
                .append("?appid=%s")
                .append("&secret=%s")
                .append("&code=%s")
                .append("&grant_type=authorization_code");
        String accessTokenUrl = String.format(baseAccessTokenUrl.toString(),
                WxConfig.WX_OPEN_APP_ID,
                WxConfig.WX_OPEN_APP_SECRET,
                code);
        return accessTokenUrl;
    }

    /**
     * 通过openid和access_token得到用户信息
     *
     * @param access_token
     * @param openid
     * @return
     */
    private String getUserInfoUrl(String access_token, String openid) {
        String baseUserInfoUrl = "https://api.weixin.qq.com/sns/userinfo" +
                "?access_token=%s" +
                "&openid=%s";
        String userInfoUrl = String.format(baseUserInfoUrl, access_token, openid);
        return userInfoUrl;
    }

回调返回页面

<template>
  <div>

  </div>
</template>

<script>

export default {
  data() {
    return {}
  },
  mounted() {
    let token = this.$route.query.token
    let name = this.$route.query.name
    this.loginCallback(token,name);
  },
  methods: { 	
    loginCallback(name, token) {
      console.log(name,token)
    },

  }
}
</script>

<style scoped>

</style>


http://www.niftyadmin.cn/n/876175.html

相关文章

Spring Boot集成阿里云对象存储OSS

Spring Boot集成阿里云对象存储OSS对象存储OSS产品优势产品功能应用场景环境准备开通对象存储OSS服务创建Bucket创建RAM子用户Spring Boot集成阿里云对象存储OSS引入依赖配置application.properties参数配置对象初始化简单上传下载文件追加上传断点续传分片上传文件管理完整Ali…

Ubuntu 18.04下Android源码的下载及编译

如何使用VMware Workstation 16 Player安装ubuntu18.04请参考《使用VMware Workstation 16 Player安装ubuntu18.04》 本文主要用于记录Android源码下载及编译的步骤和遇到的问题 安装git和repo并配置 安装git&#xff1a; sudo apt-get install git配置git的user.name和use…

Java对方法参数进行签名加密

Java对方法参数进行签名加密参数签名步骤MD5加密算法Signature签名工具类代码示例执行测试参数签名步骤 1.将请求参数中除 sign 外的多个键值对&#xff0c;按一定规则排序&#xff0c;拼成一个字符串2.将 signKey 拼接在 第一步 中排序后的字符串前/后面得到待签名字符串3.使…

定时任务组件、作业调度程序之Quartz

定时任务组件、作业调度程序之QuartzQuartz核心API基本使用添加依赖自定义Job类实现Job接口启动任务调度Spring集成Quartz定义任务类配置Quartz配置web.xml动态定时任务添加依赖导入数据表配置application.yml定时任务配置类自定义Job类实现各类定时任务Quartz Quartz是功能强…

几种常见的分布式锁实现方案

几种常见的分布式锁实现方案Jedis实现分布式锁添加依赖编码实现RedisTemplate实现分布式锁注意事项编码实现Redisson实现分布式锁添加依赖配置Redisson编码实现ZooKeeper实现分布式锁添加依赖配置Zookeeper编码实现Jedis实现分布式锁 添加依赖 <dependency><groupId&…

时序数据库之InfluxDB的安装与使用

InfluxDB时序数据库的使用InfluxDBInfluxDB概述相关概念安装InfluxDBInfluxDB的操作用户管理启用认证数据库操作数据库表操作查询操作Spring Boot集成InfluxDB添加依赖创建数据库配置InfluxDB编码执行测试InfluxDB InfluxDB概述 InfluxDB 是一个从头开始构建的时间序列数据库&…

FFmpeg+Video.js+Videojs-contrib-hls实现视频点播解决方案

FFmpegVideo.jsVideojs-contrib-hls实现视频点播解决方案视频点播解决方案HLSFFmpeg简单使用生成m3u8/ts文件码率的设置video.js下载video.js与videojs-contrib-hls常用属性与事件属性与事件的使用视频点播方案的实现页面HTML配置Nginx准备测试流媒体相关概念流媒体特征流式传输…

使用Web Uploader文件上传组件辅助Java实现断点续传

使用Web Uploader文件上传组件辅助Java实现断点续传一、断点续传断点续传概述文件分块文件合并二、Web UploaderWeb Uploader概述特点钩子方法事件三、服务端实现功能FileUploadControllerIFileUploadServiceFileUploadServiceImpl四、Web Uploader的使用引入webuploader初始化…