赞
踩
这里需要填写一个URL和一个Token验证字符串
我这里是用了natapp内网穿透 将本地的后台8080端口服务映射到了 http://x7zws8.natappfree.cc
https://natapp.cn/在natapp官网注册账号并且申请免费隧道
申请完了之后把域名绑定到自己的后台
后台接口:
@RequestMapping(value = "/check", produces = "text/plain;charset=UTF-8", method = {RequestMethod.GET, RequestMethod.POST}) //微信服务器根据配置的token,结合时间戳timestamp和随机数nonce通过SHA1生成签名,发起get请求,检验token的正确性, //检验正确原样返回随机字符串echostr,失败返回空字符串 public String check(HttpServletRequest request, HttpServletResponse response, @RequestParam("signature") String signature, @RequestParam("timestamp") String timestamp, @RequestParam("nonce") String nonce, String echostr) throws Exception { //若是为get请求,则为开发者模式验证 if ("get".equals(request.getMethod().toLowerCase())) { String checkSignature = SHA1.creatSHA1("token", timestamp, nonce); if (checkSignature.equals(signature)) { return echostr; } } return null; }
SHA1:
import java.security.MessageDigest; import java.util.Arrays; //SHA1加密算法类 public class SHA1 { /** * * @param token * @param timestamp 时间戳 * @param nonce 随机字符串 * @return 安全签名 * @throws AesException */ public static String creatSHA1(String token, String timestamp, String nonce) throws AesException { try { String[] array = new String[] { token, timestamp, nonce}; StringBuffer sb = new StringBuffer(); // 字符串排序 Arrays.sort(array); for (int i = 0; i < 3; i++) { sb.append(array[i]); } String str = sb.toString(); // SHA1签名生成 MessageDigest md = MessageDigest.getInstance("SHA-1"); md.update(str.getBytes()); byte[] digest = md.digest(); StringBuffer hexstr = new StringBuffer(); String shaHex = ""; for (int i = 0; i < digest.length; i++) { shaHex = Integer.toHexString(digest[i] & 0xFF); if (shaHex.length() < 2) { hexstr.append(0); } hexstr.append(shaHex); } return hexstr.toString(); } catch (Exception e) { e.printStackTrace(); throw new AesException(AesException.ComputeSignatureError); } } }
AesException:
public class AesException extends Exception { public final static int OK = 0; public final static int ValidateSignatureError = -40001; public final static int ParseXmlError = -40002; public final static int ComputeSignatureError = -40003; public final static int IllegalAesKey = -40004; public final static int ValidateAppidError = -40005; public final static int EncryptAESError = -40006; public final static int DecryptAESError = -40007; public final static int IllegalBuffer = -40008; private int code; private static String getMessage(int code) { switch (code) { case ValidateSignatureError: return "签名验证错误"; case ParseXmlError: return "xml解析失败"; case ComputeSignatureError: return "sha加密生成签名失败"; case IllegalAesKey: return "SymmetricKey非法"; case ValidateAppidError: return "appid校验失败"; case EncryptAESError: return "aes加密失败"; case DecryptAESError: return "aes解密失败"; case IllegalBuffer: return "解密后得到的buffer非法"; default: return null; // cannot be } } public int getCode() { return code; } public AesException(int code) { super(getMessage(code)); this.code = code; } }
校验走完之后配置测试号中 网页服务下的网页授权获取基本用户
这里填自己前端项目运行后的地址 我的后端项目端口是8080 uniapp前端运行完了之后的端口是8081所以我配置的是本地的ipv4 ip+端口号
在SpringBoot项目的pom中引入依赖
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-mp</artifactId>
<version>4.6.0</version>
</dependency>
创建配置类
import com.ruoyi.system.domain.WechatConfig; import com.ruoyi.system.service.IWechatConfigService; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl; import me.chanjar.weixin.mp.config.WxMpConfigStorage; import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class WxMpConfig { @Autowired private IWechatConfigService wechatConfigService; @Bean public WxMpConfigStorage wxMpConfigStorage() { WxMpDefaultConfigImpl configStorage = new WxMpDefaultConfigImpl(); WechatConfig wechatConfig = wechatConfigService.selectWechatConfigById(1L); //我这里是做成了获取数据库中保存的AppID和AppSercret正常情况下写死就可以 configStorage.setAppId(wechatConfig.getAppId()); configStorage.setSecret(wechatConfig.getAppSecret()); return configStorage; } @Bean public WxMpService wxMpService(WxMpConfigStorage configStorage) { WxMpService wxMpService = new WxMpServiceImpl(); wxMpService.setWxMpConfigStorage(configStorage); return wxMpService; } }
之后就可以在Controller中正常使用了
/authorize 接口其实只做了一步操作 就是构建获取code的url 构建完成之后返回给前端 前端直接重定向
buildAuthorizationUrl其中的三个参数
第一个是回调地址
第二个填snsapi_base 或者 snsapi_userinfo
snsapi_base 是之能获取到 openid 而 snsapi_userinfo 是可以获取到用户基本信息
snsapi_base是静默获取 而 snsapi_userinfo 需要用户点击授权
@RestController @RequestMapping("/wx") public class WeChatController extends BaseController { @GetMapping("/authorize") public AjaxResult test() { WxOAuth2Service oAuth2Service = wxMpService.getOAuth2Service(); String redirectUrl = oAuth2Service.buildAuthorizationUrl("http://192.168.1.100:8081", "snsapi_userinfo", null); return success(redirectUrl); } @GetMapping("/userInfo") public AjaxResult userInfo(@RequestParam("code") String code) throws WxErrorException { WxOAuth2Service oAuth2Service = wxMpService.getOAuth2Service(); WxOAuth2AccessToken wxMpOAuth2AccessToken = oAuth2Service.getAccessToken(code); logger.info("【wxMpOAuth2AccessToken:】{}", wxMpOAuth2AccessToken); String openId = wxMpOAuth2AccessToken.getOpenId(); logger.info("【openid:】{}", openId); WxOAuth2UserInfo userInfo = oAuth2Service.getUserInfo(wxMpOAuth2AccessToken, "zh_CN"); logger.info("【用户信息:】{}", userInfo.toString()); return success(userInfo); } }
前端首先调用 /authorize 获取拼装好的地址然后重定向并获取code
getUrlCode来判断地址中是否包含code如果有的话拿着code去获取用户基本信息和openid
<template> <view class="content"> <image class="logo" :src="loginUser.headImgUrl ? loginUser.headImgUrl : '/static/logo.png'"></image> <view class="text-area"> <text class="title">{{loginUser.openid}}</text> </view> <button type="default" @click="login">登录</button> </view> </template> <script> export default { data() { return { loginUser:{} } }, onLoad(query) { const that = this; let code = that.getUrlCode(); if (code) { console.log("有code") console.log(code) uni.request({ url: "http://192.168.1.100:8080/wx/userInfo", data: { code: code }, success(res) { console.log("获取到用户信息") console.log(res.data.data); that.loginUser = res.data.data; } }) } else { console.log("没有code") } }, methods: { login() { uni.request({ url: "http://192.168.1.100:8080/wx/authorize", success(res) { window.location.href = res.data.msg; } }) }, getUrlCode() { return ( decodeURIComponent( (new RegExp("[?|&]" + "code" + "=" + "([^&;]+?)(&|#|;|$)").exec( location.href ) || [, ""])[1].replace(/\+/g, "%20") ) || null ); }, } } </script>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。