建议:一定要先看官方文档

https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842

注意事项和说明官方文档都有说明,我就不说了

两种方案:第一种原生代码,我这里说第二种sdk实现,github上面有很多优秀的sdk,这里只说其一

github sdk地址:  https://github.com/Wechat-Group/weixin-java-tools/wiki

这是之前的版本,后面改名为 WXJava 了,对于新版的sdk,下面的代码有些已经不适用了,可更具新版sdk自行更改代码

本人拥有丰富的微信公众号开发和小程序开发以及支付开发经验,最近有点时间就打算写写博客

我使用的环境是springboot,ieda

使用方法:

1)第一步:

导包一一>maven或者gradle

maven:

<dependency><groupId>com.github.binarywang</groupId><artifactId>weixin-java-mp</artifactId><version>3.1.0</version>
</dependency>

gradle:

compile 'com.github.binarywang:weixin-java-mp:3.1.0'

2)第二部: 配置sdk的config

配置文件

yml中

official:appId: wx1c0abaaa92fbeef9appSecret: 5bf7cb8732af714d8540bbc5641f2df4
#  host必须加http或httpshost: http://like.s1.natapp.cc

属性config:

package com.xiaoyu.tool.configs.property;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties(prefix = "official")
@Data
public class OfficialProperty {
    private String appId;
    private String appSecret;
    private String host;
}

configuration: 重写sdk方法,使用redis管理access_token,防止两小时内每调用一次sdk方法就刷新一次access_token,此方法在分布式中尤为重要且解决了微信接口调用次数的限制

package com.xiaoyu.tool.configs;

import com.xiaoyu.tool.configs.property.OfficialProperty;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;

@Slf4j
@Configuration
@EnableConfigurationProperties(OfficialProperty.class)
public class WeixinMpConfiguration {
    private final RedisTemplate<String, String> redisTemplate;
    @Autowired
    private OfficialProperty officialProperty;

public WeixinMpConfiguration(RedisTemplate<String, String> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }
    @Bean
    public WxMpService wxMpService(){
        WxMpSpringRedisConfigStorage configStorage = new WxMpSpringRedisConfigStorage(redisTemplate);
        configStorage.setAppId(officialProperty.getAppId());
        configStorage.setSecret(officialProperty.getAppSecret());
        WxMpService wxMpService = new WxMpServiceImpl();
        wxMpService.setWxMpConfigStorage(configStorage);
        return wxMpService;
    }
}

configStorage:重写sdk底层storage

package com.xiaoyu.tool.configs;import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
import org.springframework.data.redis.core.RedisTemplate;import java.util.concurrent.TimeUnit;public class WxMpSpringRedisConfigStorage extends WxMpInMemoryConfigStorage {private final static String ACCESS_TOKEN_KEY = "wechat_access_token_";private final static String JSAPI_TICKET_KEY = "wechat_jsapi_ticket_";private final static String CARDAPI_TICKET_KEY = "wechat_cardapi_ticket_";private final RedisTemplate<String, String> redisTemplate;private String accessTokenKey;private String jsapiTicketKey;private String cardapiTicketKey;public WxMpSpringRedisConfigStorage(RedisTemplate<String, String> redisTemplate) {this.redisTemplate = redisTemplate;}@Overridepublic void setAppId(String appId) {super.setAppId(appId);
//        定义redis中存储的名称this.accessTokenKey = ACCESS_TOKEN_KEY.concat(appId);this.jsapiTicketKey = JSAPI_TICKET_KEY.concat(appId);this.cardapiTicketKey = CARDAPI_TICKET_KEY.concat(appId);}@Overridepublic String getAccessToken() {return redisTemplate.opsForValue().get(this.accessTokenKey);}@Overridepublic boolean isAccessTokenExpired() {return redisTemplate.getExpire(this.accessTokenKey) < 2;}@Overridepublic synchronized void updateAccessToken(String accessToken, int expiresInSeconds) {redisTemplate.opsForValue().set(this.accessTokenKey,accessToken,expiresInSeconds - 200, TimeUnit.SECONDS);}@Overridepublic void expireAccessToken() {redisTemplate.expire(this.accessTokenKey, 0, TimeUnit.SECONDS);}@Overridepublic String getJsapiTicket() {return redisTemplate.opsForValue().get(this.jsapiTicketKey);}@Overridepublic boolean isJsapiTicketExpired() {return redisTemplate.getExpire(this.jsapiTicketKey) < 2;}@Overridepublic synchronized void updateJsapiTicket(String jsapiTicket, int expiresInSeconds) {redisTemplate.opsForValue().set(this.jsapiTicketKey, jsapiTicket, expiresInSeconds - 200, TimeUnit.SECONDS);}@Overridepublic void expireJsapiTicket() {redisTemplate.expire(this.jsapiTicketKey, 0, TimeUnit.SECONDS);}@Overridepublic String getCardApiTicket() {return redisTemplate.opsForValue().get(this.cardapiTicketKey);}@Overridepublic boolean isCardApiTicketExpired() {return redisTemplate.getExpire(this.cardapiTicketKey) < 2;}@Overridepublic synchronized void updateCardApiTicket(String cardApiTicket, int expiresInSeconds) {redisTemplate.opsForValue().set(this.cardapiTicketKey, cardApiTicket, expiresInSeconds - 200, TimeUnit.SECONDS);}@Overridepublic void expireCardApiTicket() {redisTemplate.expire(this.cardapiTicketKey, 0, TimeUnit.SECONDS);}}

redis配置:

package com.xiaoyu.tool.configs;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;@ComponentScan
@Configuration
public class RedisConfiguration {@Beanpublic RedisTemplate<String, String> redisTemplate(RedisConnectionFactory redisConnectionFactory) {RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();redisTemplate.setConnectionFactory(redisConnectionFactory);redisTemplate.setKeySerializer(new StringRedisSerializer());redisTemplate.setValueSerializer(new StringRedisSerializer());redisTemplate.afterPropertiesSet();return redisTemplate;}}

3)第三步:具体实现 controller代码

package com.xiaoyu.tool.controller.user;import com.xiaoyu.tool.configs.property.OfficialProperty;
import com.xiaoyu.tool.entity.User.User;
import com.xiaoyu.tool.service.user.UserWebAuthorizedService;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
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 java.net.URLEncoder;/*** @Author:xiaoyu* @Created on 2018/9/17* @Description 公众号网页授权登录*/
@Controller
@RequestMapping(value = "/webAuthorized")
@Slf4j
public class UserWebAuthorizedController {private final OfficialProperty officialProperty;private final WxMpService wxMpService;private final UserWebAuthorizedService userWebAuthorizedService;public UserWebAuthorizedController(OfficialProperty officialProperty, WxMpService wxMpService, UserWebAuthorizedService userWebAuthorizedService) {this.officialProperty = officialProperty;this.wxMpService = wxMpService;this.userWebAuthorizedService = userWebAuthorizedService;}/***sdk 简单便捷*/@ApiOperation("微信网页授权")@GetMapping("/authorize")public String welcome(){//授权成功后跳转同域名下的网页String returnUrl = officialProperty.getHost() + "/index";//重定向的回调链接地址String url = officialProperty.getHost() + "/wechat_alipay_tool/webAuthorized/oauth2";String redirectUrl = wxMpService.oauth2buildAuthorizationUrl(url, WxConsts.OAuth2Scope.SNSAPI_USERINFO, URLEncoder.encode(returnUrl));return "redirect:" + redirectUrl;}@ApiOperation("授权获取用户信息")@GetMapping("/oauth2")public String oauth2(@RequestParam(name = "code") String code,@RequestParam("state") String returnUrl) {try {WxMpOAuth2AccessToken accessToken = wxMpService.oauth2getAccessToken(code);WxMpUser wxMpUser = wxMpService.oauth2getUserInfo(accessToken, "zh_CN");User user = userWebAuthorizedService.createAndUpdateUser(wxMpUser);log.info("用户信息:{}",user);} catch (WxErrorException e) {log.error("通过code获取accessToken失败/获取用户信息失败:{}",e.getMessage());}return "redirect:" + returnUrl;}}测试环境: 申请微信测试号,配置natapp域名穿透

微信测试号登录: 

https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login&token=1361182780&lang=zh_CN

配置:

这几个不要配置错了,根据自己的域名配置

natapp:

https://natapp.cn/

微信网页授权登录且实现access_token分布式管理相关推荐

  1. 微信公众号开发(一) 微信网页授权登录

    微信网页授权登录 前期准备 授权登录 获取微信数据 处理授权拒绝 前期准备 1.微信公众号开发,首先要搞一个公众号,开发阶段可以申请一个公众平台测试账号. (进入到微信公众公众平台,找到开发者工具,点 ...

  2. php微信授权ajax,ajax 实现微信网页授权登录

    项目背景 因为项目采用前后端完全分离方案,所以,无法使用常规的微信授权登录作法,需要采用 ajax 实现微信授权登录. 需求分析 因为本人是一个PHPer ,所以,微信开发采用的是 EasyWeCha ...

  3. java ajax 微信网页授权_ajax 实现微信网页授权登录的方法

    AJAX 的 ajax 实现微信网页授权登录的方法 项目背景 因为项目采用前后端完全分离方案,所以,无法使用常规的微信授权登录作法,需要采用 ajax 实现微信授权登录. 需求分析 因为本人是一个ph ...

  4. 微信网页授权登录的方法

    微信网页授权登录官方文档 微信网页授权登录的方法–推荐文章一 微信网页授权登录的方法–推荐文章二 总结: 微信授权方式(scope的属性值控制): 应用授权作用域,snsapi_base (不弹出授权 ...

  5. 微信网页授权登录java后台实现

    建议先阅读微信开发-网页授权登录官方文档: https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_au ...

  6. php微信登录代理转发,PHP微信网页授权登录

    PHP微信网页授权登录 2018年04月10日 15:44:03阅读数:601 namespace Org\WeChat; /** * 微信授权相关接口 */ class Wechat { //高级功 ...

  7. Springboot + Spring Security多种登录方式:账号用户名登录+微信网页授权登录

    一.概述 实现账号用户名+微信网页授权登录集成在Spring Security的思路,最重要的一点是要实现微信登录通过Spring Security安全框架时,不需要验证账号.密码. 二.准备工作 要 ...

  8. SpringBoot + Spring Security多种登录方式:账号+微信网页授权登录

    一.概述 实现账号用户名+微信网页授权登录集成在Spring Security的思路,最重要的一点是要实现微信登录通过Spring Security安全框架时,不需要验证账号.密码. 二.准备工作 要 ...

  9. Spring Boot Security 多种登录方式集成配置思路及方法 账号用户名登录+微信网页授权登录

    概述 实现账号用户名+微信网页授权登录集成在Spring Security的思路 前情提要 本思路完全抛弃Spring Security的配置式账号密码登录模式,采用完全独立的Filter.Provi ...

最新文章

  1. stm32 基本定时器TIM6、TIM7的使用
  2. Keyboard驱动中button中断的处理机制
  3. mysql命令行设置sqlmodel_MySQL的sql_mode模式说明及设置
  4. HTTP事务的延迟—TCP的影响
  5. 火山小视频尼尔森:2019新线消费市场人群洞察报告(附下载)
  6. Fedora 17 PHP编程环境配置
  7. oracle创建数据库用户并授权,oracle创建数据库、表空间、用户并授权
  8. netfilter与用户空间通信
  9. 如何让CSS动画中途停止并维持姿态
  10. ArcGIS API for JavaScript心得体验
  11. 启明星Exchange/outlook预定会议室终端显示解决方案
  12. JS简单获取猫眼电影所有城市完整的json数据(包括城市id和城市拼音)
  13. 读庄子-万物齐一和自然无为
  14. 7654劫持火狐解决办法
  15. cisco3560交换机的策略路由的设置
  16. 百度Java二面面经
  17. oracle存储过程初学实例
  18. 如何做一个优雅的Pod
  19. [思维模式-10]:《如何系统思考》-6- 认识篇 - 结构决定功能,如何进行深度思考
  20. 局域网steam联机_适合和基友联机一起玩的单机游戏(1)

热门文章

  1. pdffactory 打印字体_pdfFactory使用过程中的一些小技巧
  2. 美术-常用免费贴图网站分享
  3. python怎么表达我喜欢你_如何用含蓄的话表达我喜欢你 含蓄表达我喜欢你的句子大全...
  4. 安居客python二手房数据预处理
  5. 博士论文致谢火了!“我走了很远的路,吃了很多的苦,才将这份博士学位论文送到你的面前”!...
  6. 在局域网如何使用Git
  7. CSS3 动画卡顿性能优化解决方案--摘抄
  8. 基于SSM框架的湘潭大学二手物品交易平台
  9. 用python写期货程序-python如何运用在期货(我用python做期货)
  10. Linux系统之磁盘分区(基本分区和LVM逻辑卷分区)