微信扫码登录是指微信OAuth2.0授权登录让微信用户使用微信身份安全登录第三方应用或网站,在微信用户授权登录已接入微信OAuth2.0的第三方应用后,第三方可以获取到用户的接口调用凭证(access_token),通过access_token可以进行微信开放平台授权关系接口调用,从而可实现获取微信用户基本开放信息和帮助用户实现基础开放功能等。
如进去下面的网站时
https://passport.yhd.com/wechat/login.do
需要微信进行授权登录
当我们进行扫码登录后,服务器就可以通过微信开放平台获取登录用户的信息,达到对第三网站更为安全,更为人性化的体验。
地址链接:https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Wechat_Login.html
具体微信提供给开发者的文档非常详细,具体可以参照开发文档进行操作。
本次要介绍的实现微信扫码登录的第三方工具叫做:码上登录
官网地址:http://login.vicy.cn/
码上登录,是一个为各网站提供微信扫一扫登录能力的平台。
支持个人网站接入,无需企业认证, 使您的网站即刻拥有微信 [扫一扫] 登录能力!
在官网中有使用场景案例和功能介绍,可以自行查看
其中官网中最重要的一个东西:就是API文档啦
API文档:http://login.vicy.cn/apiWord.html
里面的介绍也比较详细,不过第一次使用也会有写困难,慢慢就熟悉了。
/**
* @param response
* @param map
* @return 接收参数回调,是被回调的,第三方码上登录回调
*/
@RequestMapping("/loginService")
@ResponseBody
public LoginResultVO loginService(
HttpServletResponse response,
@RequestParam Map<String, String> map) {
System.out.println(map);
userMap = map;
LoginResultVO loginResultVO = new LoginResultVO();
//System.out.println("我被调用了");
loginResultVO.setErrcode(0);
loginResultVO.setMessage("成功");
return loginResultVO;
}
项目创建的示例:当完成以上5个步骤后,一次微信扫码授权登录的过程才真正完成,也就是开发者服务器真正成功拿到了登录用户的信息数据。
由于使用码上登录必须使用公网url进行开发,所以先使用内网穿透工具,穿透本地项目到外网。
推荐使用:NATAPP—内网穿透:https://natapp.cn/
具体使用查看教程:https://natapp.cn/article
创建项目编写代码
使用到的工具
<script src="https://cdn.bootcss.com/jquery/3.3.0/jquery.min.js">script>
<script src="https://blog-static.cnblogs.com/files/lovling/jquery.qrcode.js">script>
<div id="output"></div>
<script
$('#output').qrcode({
text: qrCodeReturnUrl, // 二维码的内容
render: "canvas", // 设置渲染方式
width: 360, // 设置宽度: 默认256
height: 360, // 设置高度: 默认256
background: "#ffffff", // 背景颜色
foreground: "#000000", // 前景颜色
// src: "xxx.png", //二维码中间的图片
});
</script>
<script>
$(function(){
var code,status;
function getResult(){
var params = {
code: code,
operate: '什么操作TODO:',
};
$.ajax({
type: 'POST',
url: "请求地址TODO:",
data: params,
success: function(response) {
console.log('成功啦');
//对成功数据的操作TODO:
clearInterval(status);
},
dataType: 'json',
timeout: 30*1000,// 超时时间
// 超时意味着出错了
error: function (error) {
console.log('失败啦');
}
});
}
});
//获取code。如果code存在则调用轮询来获取数据
if(code){
status = setInterval(getResult, 1000);
}
</script>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首页title>
head>
<body>
<script>
window.location.href = "/login"
script>
body>
html>
<html>
<head>
<meta charset="UTF-8">
<title>二维码title>
<script src="https://cdn.bootcss.com/jquery/3.3.0/jquery.min.js">script>
<script src="https://blog-static.cnblogs.com/files/lovling/jquery.qrcode.js">script>
head>
<style type="text/css">
body {
background: #095f88;
}
/* 登录字体 */
.text {
color: cornsilk;
text-align: center;
margin-top: 50px;
opacity: 0.7;
}
/* 二维码 */
#output {
margin: 50px auto;
width: 360px;
padding: 0;
opacity: 0.8;
}
style>
<body>
<h1 class="text">请使用微信进行扫码登录h1>
<div class="main">
<div id="output">div>
div>
<h2 style=" text-align: center; color: #cccccc" id="msg">h2>
body>
<script type="text/javascript">
$.ajax({
type: "get",
url: "https://server01.vicy.cn/8lXdSX7FSMykbl9nFDWESdc6zfouSAEz/wxLogin/tempUserId?secretKey=62320bcb05f4428ca8b13c462e104777",
data: "data",
async: false,
dataType: "json",
success: function (response) {
// console.log('response :>> ', response);
qrCodeReturnUrl = response.data.qrCodeReturnUrl;
}
});
console.log(qrCodeReturnUrl)
$('#output').qrcode({
text: qrCodeReturnUrl, // 二维码的内容
render: "canvas", // 设置渲染方式
width: 360, // 设置宽度: 默认256
height: 360, // 设置高度: 默认256
background: "#ffffff", // 背景颜色
foreground: "#000000", // 前景颜色
// src: "http://qkongtao.cn/wp-content/uploads/2020/02/logo1.fa9c5aaa.png", //二维码中间的图片
});
//ajax的轮询
var timer1 = setInterval(checkScan, 1000);//每隔1s执行一次checkScan
var timer2 = null;
function checkScan() {
$.ajax({
type: 'get',
url: "/loginData",
// async: false,
success: function (data) {
console.log(data)
if (!$.isEmptyObject(data)) {//有用户扫描了该二维码,应停止对checkScanServlet的轮询
window.clearInterval(timer1);
console.log("拿到数据")
$('#msg').html(data.nickname + "已经扫描,请在客户端确认");//将二维码取消,防止其他人再扫
timer2 = setInterval(checkConfirm, 1000);//轮询用户是否确认登录
}
}
});
}
function checkConfirm() {
$.ajax({
type: 'get',
url: "/loginSuccess",
// async: false,
success: function () {
console.log("跳转********")
window.clearInterval(timer2);
window.location.href = "/loginSuccess"
}
});
}
script>
html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>登陆信息title>
head>
<body>
<h1 style="text-align: center;">您的登录信息h1>
<div style="width: 800px;height: 600px;margin: 50px auto;">
<h3>用户名:
<span th:text="${session.loginUser.nickname}">span>
h3>
<h3>openid:
<span th:text="${session.loginUser.userId}">span>
h3>
<h3>头像图片:
<img th:src="${session.loginUser.avatar}">
h3>
<h3>登录ip地址:
<span th:text="${session.loginUser.ipAddr}">span>
h3>
div>
body>
html>
package cn.kt.wxlogin.domain;
/**
* @author tao
* @date 2021-03-06 23:18
* 概要:
*/
public class LoginResultVO {
Integer errcode;
String message;
public Integer getErrcode() {
return errcode;
}
public void setErrcode(Integer errcode) {
this.errcode = errcode;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
@Override
public String toString() {
return "LoginResultVO{" +
"errcode=" + errcode +
", message='" + message + '\'' +
'}';
}
}
package cn.kt.wxlogin.controller;
import cn.kt.wxlogin.domain.LoginResultVO;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
/**
* @author tao
* @date 2021-03-06 23:09
* 概要:
*/
@Controller
public class WXLoginController {
/*扫码用户信息*/
private Map<String, String> userMap = new HashMap<>();
/**
* @param response
* @param map
* @return 接收参数回调,是被回调的,第三方码上登录回调
*/
@RequestMapping("/loginService")
@ResponseBody
public LoginResultVO loginService(
HttpServletResponse response,
@RequestParam Map<String, String> map) {
System.out.println(map);
userMap = map;
LoginResultVO loginResultVO = new LoginResultVO();
//System.out.println("我被调用了");
loginResultVO.setErrcode(0);
loginResultVO.setMessage("成功");
return loginResultVO;
}
/**
* @return 负责跳转登录
*/
@RequestMapping("/login")
public String login() {
return "qrcode";
}
/**
* @author :tao
* @date :Created in 2021-03-07 1:24
* @param: :
* @return: 返回前端用户信息,判断二维码有没有被扫
*/
@RequestMapping("/loginData")
@ResponseBody
public Map<String, String> loginData() {
return userMap;
}
/**
* @author :tao
* @date :Created in 2021-03-07 1:30
* @return: map
* 登陆成功,进行跳转
*/
@RequestMapping("/loginSuccess")
public ModelAndView loginSuccess(HttpServletResponse response,
Map<String, String> map,
HttpServletRequest request) {
HttpSession session = request.getSession();
/*如果session中user有值,则不需要重复*/
if (request.getSession().getAttribute("loginUser") == null) {
session.setAttribute("loginUser", userMap);
}
//清空用户数据
System.out.println(userMap);
userMap = null;
return new ModelAndView("userInfo");
}
}
链接:https://pan.baidu.com/s/1qlNECaOmMtWsOCtd_gMSqg
提取码:a9lh
复制这段内容后打开百度网盘手机App,操作更方便哦
把自己毕业设计中用到的小技术写成博客笔记,也花了很长时间整理,如果觉得对大家有帮助,可以点赞、评论、关注,长的帅的可以大方的打赏支持一下 ^ _ ^
有什么问题都可以联系我(评论就可以了!)