<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          springboot+taro實現(xiàn)小程序微信登錄并獲得手機(jī)號授權(quán)功能

          共 19466字,需瀏覽 39分鐘

           ·

          2020-12-29 15:07

          點擊上方?java項目開發(fā)選擇?設(shè)為星標(biāo)

          優(yōu)質(zhì)文章,及時送達(dá)

          --

          案例功能效果圖

          獲取手機(jī)號碼登錄頁面

          微信登錄授權(quán)頁面

          手機(jī)&微信都登錄成功頁面

          環(huán)境介紹

          前端:taro

          后端:springboot

          jdk:1.8及以上

          數(shù)據(jù)庫:mysql


          完整源碼獲取方式



          源碼獲取方式

          掃碼關(guān)注回復(fù)【wxdl】獲取完整源碼


          如果你在運行這個代碼的過程中有遇到問題,請加小編微信xxf960513,我拉你進(jìn)對應(yīng)微信學(xué)習(xí)群!!幫助你快速掌握這個功能代碼!




          核心代碼介紹

          pom.xml


          <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">  <modelVersion>4.0.0modelVersion>  <parent>    <groupId>org.springframework.bootgroupId>    <artifactId>spring-boot-starter-parentartifactId>    <version>2.4.1version>    <relativePath/>   parent>  <groupId>com.examplegroupId>  <artifactId>wechatartifactId>  <version>0.0.1-SNAPSHOTversion>  <name>wechatname>  <description>Demo project for Spring Bootdescription>
          <properties> <skipTests>trueskipTests> <java.version>1.8java.version> <maven-jar-plugin.version>2.6maven-jar-plugin.version> properties>
          <dependencies> <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starterartifactId> dependency> <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-webartifactId> dependency> <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-testartifactId> <scope>testscope> dependency> <dependency> <groupId>io.springfoxgroupId> <artifactId>springfox-swagger2artifactId> <version>2.9.2version> dependency> <dependency> <groupId>io.swaggergroupId> <artifactId>swagger-modelsartifactId> <version>1.5.21version> dependency> <dependency> <groupId>com.github.xiaoymingroupId> <artifactId>swagger-bootstrap-uiartifactId> <version>1.9.3version> dependency> <dependency> <groupId>org.apache.httpcomponentsgroupId> <artifactId>httpclientartifactId> dependency> <dependency> <groupId>org.codehaus.xfiregroupId> <artifactId>xfire-coreartifactId> <version>1.2.6version> dependency> <dependency> <groupId>org.bouncycastlegroupId> <artifactId>bcprov-jdk16artifactId> <version>1.46version> dependency> <dependency> <groupId>com.alibabagroupId> <artifactId>fastjsonartifactId> <version>1.2.62version> dependency> dependencies>
          <build> <plugins> <plugin> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-maven-pluginartifactId> plugin> plugins>??build>project>

          WeChatConfig.java

          package com.example.wechat.util;
          /** * Copyright @ 2020 Zonlyn. All rights reserved.
          * @Description: 該類的功能描述** @version: v1.0.0* @author: ducl* @date: 2020年12月16日 上午9:12:21 ** Modification History:* Date Author Version Description*---------------------------------------------------------** 2020年12月16日 ducl v1.0.0 修改原因*/public class WeChatConfig { //微信 app_id public static final String APP_ID ="your APP_ID";//"wx5a383d14e917d3ae"; //app_secret??public?static?final?String?APP_SECRET?=?"0569d415cc撒打多大9cd6a834763"; //獲取 session_key地址 public static final String USERINFO_URL = "https://api.weixin.qq.com/sns/jscode2session";}

          WeChatController.java

          package com.example.wechat.ctrler;
          import java.io.IOException;import java.io.UnsupportedEncodingException;import java.security.AlgorithmParameters;import java.security.InvalidAlgorithmParameterException;import java.security.InvalidKeyException;import java.security.NoSuchAlgorithmException;import java.security.NoSuchProviderException;import java.security.Security;import java.security.spec.InvalidParameterSpecException;import java.util.Arrays;
          import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.NoSuchPaddingException;import javax.crypto.spec.IvParameterSpec;import javax.crypto.spec.SecretKeySpec;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;
          import org.bouncycastle.jce.provider.BouncyCastleProvider;import org.codehaus.xfire.util.Base64;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.stereotype.Controller;import org.springframework.util.StringUtils;import org.springframework.web.bind.annotation.CrossOrigin;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.ResponseBody;
          import com.alibaba.fastjson.JSONObject;import com.example.wechat.bean.WeChatUserInfo;import com.example.wechat.util.HttpUtil;import com.example.wechat.util.WeChatConfig;import com.example.wechat.util.rest.CodeMsg;import com.example.wechat.util.rest.Result;
          import io.swagger.annotations.Api;import io.swagger.annotations.ApiOperation;
          /** * Copyright @ 2020 Zonlyn. All rights reserved.
          * @Description: 該類的功能描述** @version: v1.0.0* @author: ducl* @date: 2020年12月16日 上午9:03:16 ** Modification History:* Date Author Version Description*---------------------------------------------------------** 2020年12月16日 ducl v1.0.0 修改原因*/@Controller@RequestMapping("/wechat")@CrossOrigin@Api(value="微信小程序服務(wù)",tags={"微信小程序服務(wù)"})public class WeChatController { private Logger logger =LoggerFactory.getLogger(WeChatController.class); @RequestMapping(value = "/dec/userinfo", method = RequestMethod.POST) @ResponseBody @ApiOperation(value="解析登錄成功用戶信息") public Object login(@RequestBody WeChatUserInfo infoData, HttpServletRequest request, HttpServletResponse response) throws IOException { logger.info("請求的數(shù)據(jù):[{}]" + infoData); //JSONObject dataObj = JSONObject.parseObject(infoData); String code = infoData.getCode(); String encryptedData = infoData.getEncrypted_data(); String iv = infoData.getIv(); boolean paramError = StringUtils.isEmpty(code) || StringUtils.isEmpty(encryptedData) || StringUtils.isEmpty(iv); if(paramError) { return Result.error(CodeMsg.PARAMERROR); } String sessionkey = getSessionKey(code); JSONObject userInfo = this.getUserInfo(encryptedData, sessionkey, iv); logger.info("解析出的用戶信息:[{}]",userInfo); return Result.success(userInfo); } private String getSessionKey(String code) { logger.info("我的APP_ID:[{}]",WeChatConfig.APP_ID); String url = WeChatConfig.USERINFO_URL+"?appid=" + WeChatConfig.APP_ID + "&secret=" + WeChatConfig.APP_SECRET + "&js_code=" + code + "&grant_type=authorization_code"; String reusult = HttpUtil.sendGet(url, true); JSONObject oppidObj = JSONObject.parseObject(reusult); //String openid = (String) oppidObj.get("openid"); String session_key = (String) oppidObj.get("session_key"); return session_key; } /** * 獲取信息 */ private JSONObject getUserInfo(String encryptedData,String sessionkey,String iv){ // 被加密的數(shù)據(jù) byte[] dataByte = Base64.decode(encryptedData); // 加密秘鑰 byte[] keyByte = Base64.decode(sessionkey); // 偏移量 byte[] ivByte = Base64.decode(iv); try { // 如果密鑰不足16位,那么就補(bǔ)足. 這個if 中的內(nèi)容很重要 int base = 16; if (keyByte.length % base != 0) { int groups = keyByte.length / base + (keyByte.length % base != 0 ? 1 : 0); byte[] temp = new byte[groups * base]; Arrays.fill(temp, (byte) 0); System.arraycopy(keyByte, 0, temp, 0, keyByte.length); keyByte = temp; } // 初始化 Security.addProvider(new BouncyCastleProvider()); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding","BC"); SecretKeySpec spec = new SecretKeySpec(keyByte, "AES"); AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES"); parameters.init(new IvParameterSpec(ivByte)); cipher.init(Cipher.DECRYPT_MODE, spec, parameters);// 初始化 byte[] resultByte = cipher.doFinal(dataByte); if (null != resultByte && resultByte.length > 0) { String result = new String(resultByte, "UTF-8"); return JSONObject.parseObject(result); } } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (NoSuchPaddingException e) { e.printStackTrace(); } catch (InvalidParameterSpecException e) { e.printStackTrace(); } catch (IllegalBlockSizeException e) { e.printStackTrace(); } catch (BadPaddingException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (InvalidAlgorithmParameterException e) { e.printStackTrace(); } catch (NoSuchProviderException e) { e.printStackTrace(); } return null; }}

          HttpUtil.java

          ?package com.example.wechat.util;
          import java.security.cert.CertificateException;import java.security.cert.X509Certificate;import java.util.ArrayList;import java.util.List;import java.util.Map;import javax.net.ssl.SSLContext;import org.apache.http.NameValuePair;import org.apache.http.client.config.RequestConfig;import org.apache.http.client.entity.UrlEncodedFormEntity;import org.apache.http.client.methods.CloseableHttpResponse;import org.apache.http.client.methods.HttpGet;import org.apache.http.client.methods.HttpPost;import org.apache.http.client.methods.HttpRequestBase;import org.apache.http.conn.ssl.SSLConnectionSocketFactory;import org.apache.http.conn.ssl.SSLContextBuilder;import org.apache.http.conn.ssl.TrustStrategy;import org.apache.http.entity.StringEntity;import org.apache.http.impl.client.CloseableHttpClient;import org.apache.http.impl.client.HttpClientBuilder;import org.apache.http.message.BasicNameValuePair;import org.apache.http.util.EntityUtils;import org.slf4j.Logger;import org.slf4j.LoggerFactory;/** * @description httpclient 工具 * @author Administrator * */@SuppressWarnings("deprecation")public class HttpUtil { private static Logger logger = LoggerFactory.getLogger(HttpUtil.class); private static final int Format_KeyValue = 0; private static final int Format_Json = 1; private static final int SOCKET_TIMEOUT = 60 * 1000; private static final int CONN_TIMEOUT = 60 * 1000;
          /** * 創(chuàng)建HttpClient客戶端 * * @param isHttps * @return */ private static CloseableHttpClient createClient(boolean isHttps) { HttpClientBuilder httpClientBuilder = HttpClientBuilder.create(); if (isHttps) { try { SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() { // 信任所有 @Override public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException { return true; } }).build(); SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext,SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); httpClientBuilder.setSSLSocketFactory(sslsf); } catch (Exception e) { e.printStackTrace(); logger.error("創(chuàng)建HTTPS客戶端異常"); } } return httpClientBuilder.build(); }
          /** * 支持 http、https協(xié)議 * 調(diào)用Get接口 * @param url 接口地址 * @param isHttps [true:https協(xié)議,false:http協(xié)議] * @return */ public static String sendGet(String url, boolean isHttps) { CloseableHttpClient httpClient = createClient(isHttps); if (url == null || "".equals(url)) { logger.error("接口地址為空"); return null; } HttpGet request = null; try { request = new HttpGet(url); if (httpClient == null) { logger.error("HttpClient實例為空"); return null; } setTimeOut(request); CloseableHttpResponse response = httpClient.execute(request); if (response.getStatusLine().getStatusCode() == 200) { return EntityUtils.toString(response.getEntity()); } } catch (Exception e) { logger.error("訪問接口失敗,接口地址為:" + url); } finally { if (request != null) request.releaseConnection(); } return null; }
          /** * 調(diào)用Post接口 * * @param url 接口地址 * @param params 參數(shù) * @param type 參數(shù)類型,0:鍵值對,1:json數(shù)據(jù) * @param isHttps 參數(shù)類型 false:http協(xié)議,true:https協(xié)議 * @return */ public static String sendPost(String url, String parameters, int type, boolean isHttps) { CloseableHttpClient httpClient = createClient(isHttps); if (url == null || "".equals(url)) { logger.error("接口地址為空"); return null; } HttpPost request = null; try { request = new HttpPost(url); if (httpClient == null) { logger.error("HttpClient實例為空"); return null; } setTimeOut(request); StringEntity entity = new StringEntity(parameters, "UTF-8"); if (type == Format_KeyValue) {// request.addHeader("Content-Type", "application/x-www-form-urlencoded"); entity.setContentType("application/x-www-form-urlencoded"); } else if (type == Format_Json) {// request.addHeader("Content-Type", "application/json"); entity.setContentType("application/json"); } else { logger.error("不支持的參數(shù)格式"); return null; } request.setEntity(entity); CloseableHttpResponse response = httpClient.execute(request); if (response.getStatusLine().getStatusCode() == 200) { return EntityUtils.toString(response.getEntity()); } } catch (Exception e) { logger.error("訪問接口失敗,接口地址為:" + url); throw new RuntimeException(e.getMessage()); } finally { if (request != null) request.releaseConnection(); } return null; }
          /** * 調(diào)用Post接口,參數(shù)為鍵值對方式 * * @param url 接口地址 * @param params 鍵值對參數(shù) * @param isHttps 參數(shù)類型 false:http協(xié)議,true:https協(xié)議 * @return */ public static String sendPostByKeyValue(String url, Map params, boolean isHttps) { CloseableHttpClient httpClient = createClient(isHttps); if (url == null || "".equals(url)) { logger.error("接口地址為空"); return null; } HttpPost request = null; try { request = new HttpPost(url); if (httpClient == null) { logger.error("HttpClient實例為空"); return null; } setTimeOut(request); List nvps = new ArrayList(); for (Map.Entry entry : params.entrySet()) { nvps.add(new BasicNameValuePair(entry.getKey(), entry.getValue())); } request.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8")); CloseableHttpResponse response = httpClient.execute(request); if (response.getStatusLine().getStatusCode() == 200) { return EntityUtils.toString(response.getEntity()); } } catch (Exception e) { logger.error("訪問接口失敗,接口地址為:" + url); } finally { if (request != null) request.releaseConnection(); } return null; }
          /** * 調(diào)用Post接口,參數(shù)為JSON格式 * * @param url 接口地址 * @param params json數(shù)據(jù) * @param isHttps 參數(shù)類型 false:http協(xié)議,true:https協(xié)議 * @return */ public static String sendPostByJson(String url, String params,boolean isHttps) { return sendPost(url, params, Format_Json, isHttps); } /** * 設(shè)置 請求超時 * @author ducl * @param methodType void * @date 2020年7月1日上午8:55:44 */ private static void setTimeOut(HttpRequestBase methodType){ RequestConfig config = RequestConfig.custom() .setConnectTimeout(SOCKET_TIMEOUT) .setConnectionRequestTimeout(CONN_TIMEOUT) .setSocketTimeout(SOCKET_TIMEOUT).build(); methodType.setConfig(config); } }

          home.js

          /** @format */import { ApiConfig } from "../utils/config";
          export default { wechatPhone: { name: "wechatPhone", method: "POST", desc: "拿到微信手機(jī)號碼", path: ApiConfig.baseUrl + "/yxyz/wechat/dec/userinfo" }};

          index.jsx

          import Taro from "@tarojs/taro";import React from "react";import { View, Text, Image, Button } from "@tarojs/components";import { AtList, AtListItem, AtIcon } from "taro-ui";import { getData } from "../../utils/request";import home from "../../api/home";import "./index.scss";import { checkStaticImg } from "../../utils";import { connect } from "react-redux";import { commitUserInfo } from "../../store/actions";
          const mapStateToProps = state => { return { userInfo: state.my.userInfo };};
          const mapDispatchToProps = { commitUserInfo};
          @connect(mapStateToProps, mapDispatchToProps)class My extends React.Component { state = { code: "" };
          componentDidMount = async () => { const that = this; Taro.login({ success: function(res) { console.log(res, "code"); if (res.code) { that.setState({ code: res.code }); } } }); };
          getUserInfo = res => { console.log(res, "res");
          if (res.detail && res.detail.userInfo) { this.props.commitUserInfo({ ...this.props.userInfo, ...res.detail.userInfo }); } };
          getPhoneNumber = res => { console.log(res, "res");
          if (res.detail) { let params = { code: this.state.code, encrypted_data: res.detail.encryptedData, iv: res.detail.iv }; console.log(this.userInfo); getData(params, home.wechatPhone).then(res => { console.log(res, "mydata"); if (res.data.phoneNumber) { let userInfo = { ...this.props.userInfo, phoneNumber: res.data.phoneNumber }; this.props.commitUserInfo(userInfo); } }); } console.log(res, "res"); }; render() { let { userInfo } = this.props; return ( <View className="my-wrap"> {userInfo.nickName ? ( <View class="top-wrap"> <View class="top-wrap-con"> <Image class="logo" src={userInfo.avatarUrl}>Image> <View class="top-con"> <Text class="title">{userInfo.nickName}Text> {/* <Text class="title">性別:{userInfo.gender === 1 ? "男" : "女"}Text> <Text class="title"> 地址:{userInfo.province}/{userInfo.city} Text> */} {userInfo.phoneNumber ? <Text class="phone">{userInfo.phoneNumber}Text> : null} View> <AtIcon prefixClassName="iconfont" value="edit-outline" size="16" color={"#999"} className={`iconfont icon-edit-outline`} >AtIcon> View> {/* {userInfo.phoneNumber ? null : ( <Button open-type="getPhoneNumber" onGetPhoneNumber={this.getPhoneNumber} class="phone-btn"> 手機(jī)號 Button> )} */} View> ) : ( <View class="top-wrap"> <Button open-type="getUserInfo" onGetUserInfo={this.getUserInfo} class="no-login"> <Image class="img" src={checkStaticImg("login.png")}>Image> <View class="login-label"> <Text class="login-label-title">點擊登錄Text> {userInfo.phoneNumber ? <Text class="phone">{userInfo.phoneNumber}Text> : null} View> Button> View> )} {userInfo.phoneNumber ? null : ( <Button open-type="getPhoneNumber" onGetPhoneNumber={this.getPhoneNumber} class="phone-btn"> 點我獲取手機(jī)號 Button> )} <View class="sep">View> <AtList className="list"> <Button openType="contact" className="btn-item"> <AtListItem title="聯(lián)系客服" thumb={checkStaticImg("contact.png")} arrow="right" className="list-item" /> Button> <Button openType="feedback" className="btn-item"> <AtListItem title="意見反饋" thumb={checkStaticImg("feedback.png")} arrow="right" className="list-item" /> Button> {/* <Button openType="contact" className="btn-item"> <Image src={checkStaticImg("contact.png")} className="btn-img">Image> <Text className="btn-text">聯(lián)系客服Text> Button> */} AtList> {/* <View className="btn-wrap"> <Button openType="feedback" className="btn-item"> <Image src={checkStaticImg("feedback.png")} className="btn-img">Image> <Text className="btn-text">意見反饋Text> Button> <Button openType="contact" className="btn-item"> <Image src={checkStaticImg("contact.png")} className="btn-img">Image> <Text className="btn-text">聯(lián)系客服Text> Button> View> */} View> ); }}export default My;

          request.js

          /**?@format?*/// axios 默認(rèn)配置export const ApiConfig = {  baseUrl: "http://XXX.XXX.XXX.XXX:8000/"};
          -?END -

          推薦案例

          溫暖提示

          為了方便大家更好的學(xué)習(xí),本公眾號經(jīng)常分享一些完整的單個功能案例代碼給大家去練習(xí),如果本公眾號沒有你要學(xué)習(xí)的功能案例,你可以聯(lián)系小編(微信:xxf960513)提供你的小需求給我,我安排我們這邊的開發(fā)團(tuán)隊免費幫你完成你的案例。
          注意:只能提單個功能的需求不能要求功能太多,比如要求用什么技術(shù),有幾個頁面,頁面要求怎么樣?


          請長按識別二維碼

          想學(xué)習(xí)更多的java功能案例請關(guān)注

          Java項目開發(fā)

          如果你覺得這個案例以及我們的分享思路不錯,對你有幫助,請分享給身邊更多需要學(xué)習(xí)的朋友。別忘了《留言+點在看》給作者一個鼓勵哦!

          瀏覽 83
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  色老板精品永久免费视频 | 玖玖精品| 日韩三级视频网站 | 人人做爱 | 欧美精品久久久久 |