This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money.
Introduction to the
There are two ways to scan wechat web pages for login authorization:
- The first type: Based on the wechat public account, obtain the qr code for login separately, and then scan the code for login. The program controls the jump logic, such as CSDN:
- Second: Based on the wechat open platform, jump to the wechat TWO-DIMENSIONAL code page for scanning code login and redirect to the success page, such as Youdao Note:
Note:This paper records the first way, just through the wechat test public account can complete the test, that is, everyone can run completely locally; The second requires a developer account with a certified qualification, which will be recorded later.
A complete local operating environment is available
Intranet penetration => Generate the extranet domain name of the specified local port mapping
Portal:Details on the use of Intranet penetration tool Natapp Modify configuration file after domain name generation:
Register and configure wechat test public account
- Registered address: Wechat public platform test account application, scan code to log in, and follow the test number
- Get the test number AppID and AppSecret
3. Interface configuration modification (The background signature verification method is called back. You need to start the background during configuration)4. Configure the authorized domain name for obtaining wechat user information
process
Text briefly
- Page click to obtain the wechat login TWO-DIMENSIONAL code button
- The background uses appID and appsecret as parameters to call wechat API to obtain access_token
- Call wechat API with access_token as parameter to obtain local wechat login QR code ticket, and pass the random string parameter scene_str. This participation can be used by the program to verify whether the code scanning is successful
- If the QR code is successfully obtained through ticket, the page is displayed. At the same time, the foreground starts js scheduled tasks (which can be optimized into background notifications), and monitors whether the code scanning is successful
- The user successfully scanned the code on wechat
- Wechat server callback Local server signature verification interface verifies signature and callback processing
- The callback process determines that the sweep was successful (you can also verify this with attention) and that the database or cache inserts a record of the local sweep success
- The periodic task in the foreground obtains the code sweep success record or the background proactively notifies it to process the code sweep success
code
1. Obtain the wechat QR code and start the JS scheduled task
The front desk HTML
<h1>Wechat code scanning login method 1</h1>
<button onclick="getQrCode()" style="width: 100px; height: 50px;">Get the QR code</button>
<br>
<img src="" id="qrCodeImgId" style="width: 300px; height: 300px; display: none">
<hr>
Copy the code
The front desk js
/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = WeChat scan code means a = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
// Stores the QR code to verify whether the scan is successful
var sceneStr;
var t;
// Get the login qr code
function getQrCode(){
$.get('qrCodeFirstLogin/getQrCode'.function (data) {
console.log("=============getQrCode=======================");
console.log(data);
if(data.code == 200){
sceneStr = data.data.sceneStr;
// Obtain the qr code
$('#qrCodeImgId').attr('src'."https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket="+data.data.ticket);
$('#qrCodeImgId').show();
// Check whether the scheduled task is scanning codes successfully
t = window.setInterval(getOpenId,3000);
}else{ alert(data.msg); }}); }Copy the code
The ticket interface with a QR code is obtained from the background
/** * get accessToken *@return* /
public String getAccessToken(a){
String accessToken = null;
String getTokenUrl = wxConfig.getTokenUrl().replace("APPID", wxConfig.getAppId()).replace("SECRET", wxConfig.getAppSecret());
String result = HttpClientUtil.doGet(getTokenUrl);
JSONObject jsonObject = JSONObject.parseObject(result);
accessToken = jsonObject.getString("access_token");
return accessToken ;
}
/** * Obtain the login qr code *@return* /
@GetMapping("/getQrCode")
private ResultJson getQrCode(a){
try {
// Get token developers
String accessToken =getAccessToken();
String getQrCodeUrl = wxConfig.getQrCodeUrl().replace("TOKEN", accessToken);
// Generate a qr code with parameters scene_str
String sceneStr = CodeLoginUtil.getRandomString(8);
String json="{\"expire_seconds\": 604800, \"action_name\": \"QR_STR_SCENE\"" +", \"action_info\": {\"scene\": {\"scene_str\": \""+sceneStr+"\"}}}";
String result = HttpClientUtil.doPostJson(getQrCodeUrl,json);
JSONObject jsonObject = JSONObject.parseObject(result);
jsonObject.put("sceneStr",sceneStr);
return ResultJson.ok(jsonObject);
} catch (Exception e) {
e.printStackTrace();
returnResultJson.error(e.getMessage()); }}Copy the code
2. Signature verification and callback processing
/** * Verify signature *@param request
* @return
* @throws Exception
*/
@RequestMapping("/checkSign")
public String checkSign ( HttpServletRequest request) throws Exception {
log.info("===========>checkSign");
// Get wechat request parameters
String signature = request.getParameter ("signature");
String timestamp = request.getParameter ("timestamp");
String nonce = request.getParameter ("nonce");
String echostr = request.getParameter ("echostr");
// Sort parameters. The token is replaced by the token you actually wrote
String [] params = new String [] {timestamp,nonce,"123456"}; Arrays.sort (params) ;/ / stitching
String paramstr = params[0] + params[1] + params[2];/ / encryption
// Get the shAL algorithm encapsulation class
MessageDigest Sha1Dtgest = MessageDigest.getInstance("SHA-1");// Encrypt
byte [] digestResult = Sha1Dtgest.digest(paramstr.getBytes ("UTF-8"));
// get the encryption result
String mysignature = CodeLoginUtil.bytes2HexString(digestResult);
mysignature=mysignature.toLowerCase(Locale.ROOT);
// Is this correct
boolean signsuccess = mysignature.equals(signature);
// Logical processing
if(signsuccess && echostr! =null) {
//peizhi token
return echostr ;// If not, return a failure message.
}else{
JSONObject jsonObject = callback(request);
returnjsonObject.toJSONString(); }}/** * callback method *@param request
* @return
* @throws Exception
*/
public JSONObject callback(HttpServletRequest request) throws Exception{
log.info("===========>callback");
// There is corresponding information in the request
WxMpXmlMessage message= WxMpXmlMessage.fromXml(request.getInputStream());// Get the message flow and parse the XML
String messageType=message.getMsgType(); // Message type
String messageEvent=message.getEvent(); // Message event
// openid
String fromUser=message.getFromUser(); // Sender account
String touser=message.getToUser(); // Developer wechat id
String text=message.getContent(); // Text message text content
// Special parameters passed when generating the QR code
String eventKey=message.getEventKey(); // Code parameters
String uuid=""; // Obtain the UUID from the two-dimensional code parameters. The UUID can be used to transmit data through the websocket front end
String userid="";
//if query
JSONObject jsonObject = new JSONObject();
jsonObject.put("code"."200");
if(messageType.equals("event")){
jsonObject = null;
// Query user information from the openID database => jsonObject
if(messageEvent.equals("SCAN")) {// Scan the qr code
//return "welcome back ";
}
if(messageEvent.equals("subscribe")) {/ / concern
//return "Thank you for your attention ";
}
// There is no such user
if(jsonObject==null) {// Pull user information from wechat
String url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=" +getAccessToken() +
"&openid=" + fromUser +
"&lang=zh_CN";
String result = HttpClientUtil.doGet(url);
jsonObject = JSONObject.parseObject(result);
/** * user information processing.... * /
}
// The code is scanned successfully and stored in cache
loginMap.put(eventKey,new CodeLoginKey(eventKey,fromUser));
return jsonObject;
}
return jsonObject;
/ / the log. The info (" message types: {}, news events: {}, the sender account: {}, the receiver WeChat: {}, a text message: {}, qr code parameters: {} ", messageType, messageEvent, fromUser, touser, text, eventKey);
}
Copy the code
3. The user information is obtained successfully. Cancel the scheduled task
Js periodic task monitoring
// If the scan succeeds and user openId is obtained => Prepare for obtaining user information
function getOpenId() {
$.get("qrCodeFirstLogin/getOpenId", {"eventKey":sceneStr
},function (data) {
if(data.code == 200) {console.log("========getOpenId==========");
console.log(data.data);
window.clearInterval(t);
alert("Login successful openId:"+data.data.openId);
/** * 1. Bind the account by scanning the code for the first time. 2}}); }Copy the code
Background authentication interface
/** * Obtain user openId according to qr code identifier => Obtain user information *@param eventKey
* @return* /
@RequestMapping("getOpenId")
public ResultJson getOpenId(String eventKey){
if(loginMap.get(eventKey) == null) {return ResultJson.error("No code scan success!"); } CodeLoginKey codeLoginKey = loginMap.get(eventKey); loginMap.remove(eventKey);return ResultJson.ok(codeLoginKey);
}
Copy the code
The results demonstrate
Get the QR code
Sweep code success
The source code
Portal: wechat PC scan code login