2016-05-06 09:24:32 zhangxc0310 阅读数 29376
  • 微信支付开发-微信公众号开发12-微信开发php

    微信公众平台开发之微信支付开发是子恒老师《微信公众平台开发》视频教程的第12部。详细讲解了用php进行微信支付的开发。内容包含获取支付密钥,微信公众号支付开发,扫码支付,微信刷卡支付,异步处理支付结果等等。欢迎反馈,微信/QQ:68183131

    27842 人正在学习 去看看 秦子恒

做微信开发的人都知道,access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token,我前几天做项目的时候,偶尔会有好多用户的信息获取不到,还有生成二维码报错,打印log才发现,access_token已经失效,但access_token的有效期是7200S也就是两个小时,但我的token失效的时候才30分钟左右,其他地方也没有单独调用获取token的接口,让人匪夷所思。

实在没有办法了,只能用一个迂回的招,就是调用微信一个没有次数限制的接口,把access_token传过去,接受返回值判断token的有效性。



首先是判断token的有效期 

<pre name="code" class="csharp">public string isExpires() { 
string sqlStr = "select ACCESS_TOKEN,ROW_ID,END_DATE from CD_TOKEN where DELETE_FLAG='N'"; 
//进行判断 
string nowTag = getTimestamp();
//当前时间的秒数 
DataSet ds=dao.GetDataSet(sqlStr); 
if (ds.Tables[0].Rows.Count == 1) 
{ 
if (Convert.ToInt32(ds.Tables[0].Rows[0]["END_DATE"].ToString()) > Convert.ToInt32(nowTag)) 
{ 
return ds.Tables[0].Rows[0]["ACCESS_TOKEN"].ToString(); 
} else { 
return "false"; 
}
 } 
return "false"; 
}





然后重点来了,当token没有过期,但已经失效的情况怎么办呢。

<pre name="code" class="csharp">public string GetNewAccess_token() {
 //判断access-token是否有效?
 string result = access_tokenDao.isExpires(); 
if (result == "false")//无效 
{ 
//刷新access_token 
string token = GetAccess_token().access_token;
//获取最新的access_token 
//将新的token存入进数据库 
string startDate = getTimestamp(); 
string endDate = (Convert.ToInt32(startDate) + 6000) + ""; 
Boolean t = access_tokenDao.refreshToken(token, startDate, endDate, "7200"); 
return token; } 
//调用第三个接口,验证token有效性 
string url = "https://api.weixin.qq.com/cgi-bin/getcallbackip?access_token="+result; 
string ip = new ApplicationUtil().DealGet(url);
 //Log.Info("err", s); 
IPtest iptest = new IPtest(); 
iptest = WXJSONHelper.ParseFromJson<iptest>(ip); 
string errorcode = iptest.errcode; 
if (errorcode != null) 
{ 
string token = GetAccess_token().access_token;
//获取最新的access_token 
//将新的token存入进数据库 
string startDate = getTimestamp(); 
string endDate = (Convert.ToInt32(startDate) + 6000) + ""; 
Boolean t = access_tokenDao.refreshToken(token, startDate, endDate, "7200"); 
return token; 
}
 return result; 
}






差不多就这样吧,第一次写。。。





2016-10-31 11:56:42 u012082367 阅读数 113
  • 微信支付开发-微信公众号开发12-微信开发php

    微信公众平台开发之微信支付开发是子恒老师《微信公众平台开发》视频教程的第12部。详细讲解了用php进行微信支付的开发。内容包含获取支付密钥,微信公众号支付开发,扫码支付,微信刷卡支付,异步处理支付结果等等。欢迎反馈,微信/QQ:68183131

    27842 人正在学习 去看看 秦子恒

首先我们要清楚h5页面的请求流程

在第一次授权的时候

客户端请求url

微信返回客户端一个code

当用户点击同意授权的时候,将code带过去,获取access_token和openId ,code有效期为5分钟,access_token为全局的唯一票据,有效期为两个小时,当过期的时候需重新获取

openid是用户在此公众服务号的一个唯一标识

access_token是当你要去微信服务器去请求用户基本信息的时候的一个凭证

简单来说 就是   客户端————微信服务器————第三方服务器

三者之间进行交互

 

首先先新建一个微信数据存放类WeixinOauth2Token

 

package com.wonder.entity;

/**
 * Created by Guozhijie on 2016/10/27.
 */
public class WeixinOauth2Token {
    // 网页授权接口调用凭证
    private String accessToken;
    // 凭证有效时长
    private int expiresIn;
    // 用于刷新凭证
    private String refreshToken;
    // 用户标识
    private String openId;
    // 用户授权作用域
    private String scope;

    public String getAccessToken() {
        return accessToken;
    }

    public void setAccessToken(String accessToken) {
        this.accessToken = accessToken;
    }

    public int getExpiresIn() {
        return expiresIn;
    }

    public void setExpiresIn(int expiresIn) {
        this.expiresIn = expiresIn;
    }

    public String getRefreshToken() {
        return refreshToken;
    }

    public void setRefreshToken(String refreshToken) {
        this.refreshToken = refreshToken;
    }

    public String getOpenId() {
        return openId;
    }

    public void setOpenId(String openId) {
        this.openId = openId;
    }

    public String getScope() {
        return scope;
    }

    public void setScope(String scope) {
        this.scope = scope;
    }
}

 

 

微信用户信息类weixinUserInfo

 

package com.wonder.entity;

/**
 * Created by Guozhijie on 2016/10/27.
 */
public class WeixinUserInfo {
    // 用户的标识
    private String openId;
    // 关注状态(1是关注,0是未关注),未关注时获取不到其余信息
    private int subscribe;
    // 用户关注时间,为时间戳。如果用户曾多次关注,则取最后关注时间
    private String subscribeTime;
    // 昵称
    private String nickname;
    // 用户的性别(1是男性,2是女性,0是未知)
    private int sex;
    // 用户所在国家
    private String country;
    // 用户所在省份
    private String province;
    // 用户所在城市
    private String city;
    // 用户的语言,简体中文为zh_CN
    private String language;
    // 用户头像
    private String headImgUrl;

    public String getOpenId() {
        return openId;
    }

    public void setOpenId(String openId) {
        this.openId = openId;
    }

    public int getSubscribe() {
        return subscribe;
    }

    public void setSubscribe(int subscribe) {
        this.subscribe = subscribe;
    }

    public String getSubscribeTime() {
        return subscribeTime;
    }

    public void setSubscribeTime(String subscribeTime) {
        this.subscribeTime = subscribeTime;
    }

    public String getNickname() {
        return nickname;
    }

    public void setNickname(String nickname) {
        this.nickname = nickname;
    }

    public int getSex() {
        return sex;
    }

    public void setSex(int sex) {
        this.sex = sex;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public String getProvince() {
        return province;
    }

    public void setProvince(String province) {
        this.province = province;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getLanguage() {
        return language;
    }

    public void setLanguage(String language) {
        this.language = language;
    }

    public String getHeadImgUrl() {
        return headImgUrl;
    }

    public void setHeadImgUrl(String headImgUrl) {
        this.headImgUrl = headImgUrl;
    }
}

 

 

服务器证书通行证类

 

package com.wonder.Util;

import javax.net.ssl.X509TrustManager;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

/**
 * Created by Guozhijie on 2016/10/27.
 */
public class MyX509TrustManager implements X509TrustManager {
    // 检查客户端证书
    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
    }

    // 检查服务器端证书
    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
    }

    // 返回受信任的X509证书数组
    public X509Certificate[] getAcceptedIssuers() {
        return null;
    }
}

 请求工具类

package com.wonder.Util;

import com.wonder.entity.WeixinOauth2Token;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.ConnectException;
import java.net.URL;

/**
 * Created by Guozhijie on 2016/10/27.
 */
public class CommonUtil {

    private static Logger log = LoggerFactory.getLogger(CommonUtil.class);

    // 凭证获取(GET)
    public final static String token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";

    /**
     * 发送https请求
     *
     * @param requestUrl 请求地址
     * @param requestMethod 请求方式(GET、POST)
     * @param outputStr 提交的数据
     * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
     */
    public static JSONObject httpsRequest(String requestUrl, String requestMethod, String outputStr) {
        JSONObject jsonObject = null;
        try {
            // 创建SSLContext对象,并使用我们指定的信任管理器初始化
            TrustManager[] tm = { new MyX509TrustManager() };
            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
            sslContext.init(null, tm, new java.security.SecureRandom());
            // 从上述SSLContext对象中得到SSLSocketFactory对象
            SSLSocketFactory ssf = sslContext.getSocketFactory();

            URL url = new URL(requestUrl);
            HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
            conn.setSSLSocketFactory(ssf);

            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setUseCaches(false);
            // 设置请求方式(GET/POST)
            conn.setRequestMethod(requestMethod);

            // 当outputStr不为null时向输出流写数据
            if (null != outputStr) {
                OutputStream outputStream = conn.getOutputStream();
                // 注意编码格式
                outputStream.write(outputStr.getBytes("UTF-8"));
                outputStream.close();
            }

            // 从输入流读取返回内容
            InputStream inputStream = conn.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            String str = null;
            StringBuffer buffer = new StringBuffer();
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }

            // 释放资源
            bufferedReader.close();
            inputStreamReader.close();
            inputStream.close();
            inputStream = null;
            conn.disconnect();
            jsonObject = JSONObject.fromObject(buffer.toString());
        } catch (ConnectException ce) {
            log.error("连接超时:{}", ce);
        } catch (Exception e) {
            log.error("https请求异常:{}", e);
        }
        return jsonObject;
    }

    /**
     * 获取接口访问凭证
     *
     * @param appid 凭证
     * @param appsecret 密钥
     * @return
     */
    public static WeixinOauth2Token getToken(String appid, String appsecret, HttpServletRequest request) {
        WeixinOauth2Token wat = null;
        String requestUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
        requestUrl = requestUrl.replace("APPID", appid);
        requestUrl = requestUrl.replace("SECRET", appsecret);
        requestUrl = requestUrl.replace("CODE", request.getParameter("code"));
        // 发起GET请求获取凭证
        JSONObject jsonObject = httpsRequest(requestUrl, "GET", null);

        if (null != jsonObject) {
            try {
                wat = new WeixinOauth2Token();
                wat.setAccessToken(jsonObject.getString("access_token"));
                wat.setExpiresIn(jsonObject.getInt("expires_in"));
                wat.setRefreshToken(jsonObject.getString("refresh_token"));
                wat.setOpenId(jsonObject.getString("openid"));
                wat.setScope(jsonObject.getString("scope"));
            } catch (JSONException e) {
                wat = null;
                // 获取token失败
                log.error("获取token失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));
            }
        }
        return wat;
    }

    /**
     * URL编码(utf-8)
     *
     * @param source
     * @return
     */
    public static String urlEncodeUTF8(String source) {
        String result = source;
        try {
            result = java.net.URLEncoder.encode(source, "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 根据内容类型判断文件扩展名
     *
     * @param contentType 内容类型
     * @return
     */
    public static String getFileExt(String contentType) {
        String fileExt = "";
        if ("image/jpeg".equals(contentType))
            fileExt = ".jpg";
        else if ("audio/mpeg".equals(contentType))
            fileExt = ".mp3";
        else if ("audio/amr".equals(contentType))
            fileExt = ".amr";
        else if ("video/mp4".equals(contentType))
            fileExt = ".mp4";
        else if ("video/mpeg4".equals(contentType))
            fileExt = ".mp4";
        return fileExt;
    }
}

 

 

然后在访问的时候做一个拦截interceptor

package com.wonder.interceptor;

import com.wonder.Util.CommonUtil;
import com.wonder.entity.WeixinOauth2Token;
import com.wonder.entity.WeixinUserInfo;
import com.wonder.threadLocal.UserIdThreadLocal;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

/**
 * Created by Guozhijie on 2016/10/27.
 */
public class WechatInterceptor  implements HandlerInterceptor {
    public   boolean preHandle(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse, Object handler) throws Exception{
        String uri=httpServletRequest.getRequestURI();
        WeixinUserInfo user=(WeixinUserInfo) httpServletRequest.getSession().getAttribute("user");
        if(user!=null){
            UserIdThreadLocal.setOpenId(Long.parseLong(user.getOpenId()));
            return true;
        }
        else{

            try{
                String code=httpServletRequest.getParameter("code");
                if(StringUtils.isEmpty(code)){
                   httpServletResponse.sendRedirect(getUrl(httpServletRequest));
                    return false;
                }
                else{
                    String appid="wxd1f88b3343475e07";
                    String appSecret="*************";
                    WeixinOauth2Token token= CommonUtil.getToken(appid,appSecret,httpServletRequest);
                    UserIdThreadLocal.setOpenId( Long.parseLong(token.getOpenId()));
                    WeixinUserInfo weixinUserInfo=new WeixinUserInfo();
                    weixinUserInfo.setOpenId(token.getOpenId());
                    httpServletRequest.getSession().setAttribute("user",weixinUserInfo);
                    return true;
                }
            }catch (Exception e){
                e.printStackTrace();
                httpServletResponse.sendRedirect(getUrl(httpServletRequest));
                return false;
            }

        }

    }

    @Override
    public   void postHandle(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse, Object o, org.springframework.web.servlet.ModelAndView modelAndView) throws Exception{}

    @Override
    public void afterCompletion(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception{}


    public String getUrl(HttpServletRequest request)throws UnsupportedEncodingException{
       String requestUrl=request.getRequestURL().toString();
        String redirectUri= URLEncoder.encode(requestUrl,"utf-8");
        String appid="wxd1f88b3343475e07";
        String url="https://open.weixin.qq.com/connect/oauth2/authorize?appid="+appid+"&redirect_uri="+redirectUri+"&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect";
        return url;
    }
}

 

拦截的作用就是在开始授权通过时候,如果此用户是第一次,则走login方法,然后通过appId ,跟secret ,code 来获取access_token 和openid ,unionid 并存入数据库

如果已经在session中有了此用户则直接访问

若访问没有code参数,且没有授权  则走geturl获取code 去授权页面

 

此时有一个疑问就是当你 授权了   且 第二次访问此url的时候是怎么一个访问情况,

其实在你第二次访问的时候 若你的Session已过期了,还可以访问,是因为在微信服务器端 根据你的unionid

来判断你是否做过授权 然后再给你一个code 此时 由于有了code参数   拿到openId去数据库已查询发现有了此用户,可以直接访问

 

 

需要注意的是 scope 权限,分两种  

 

应用授权作用域,snsapi_base (不弹出授权页面,直接跳转,只能获取用户openid),snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息

 

 

 

 

2018-06-26 14:08:04 m0_37668842 阅读数 141
  • 微信支付开发-微信公众号开发12-微信开发php

    微信公众平台开发之微信支付开发是子恒老师《微信公众平台开发》视频教程的第12部。详细讲解了用php进行微信支付的开发。内容包含获取支付密钥,微信公众号支付开发,扫码支付,微信刷卡支付,异步处理支付结果等等。欢迎反馈,微信/QQ:68183131

    27842 人正在学习 去看看 秦子恒

一些参数的解释说明

pre_auth_code :第三方的预授权码,过期时间30分钟,通过第三方appId获取

component_verify_ticket:出于安全考虑,在第三方平台创建审核通过后,微信服务器 每隔10分钟会向第三方的消息接收地址推送一次

                                        component_verify_ticket,第三方平台接口获取component_access_token接口调用凭据(即令牌)需要

                                        component_verify_ticket参数。

component_access_token: 第三方接口的调用凭据,也叫做令牌,有效期两小时,调用次数有限,建议本地存储,快到2小时去请求刷新,更新本地令牌




未完,待续。。。

2019-06-06 16:37:01 qq_30604453 阅读数 770
  • 微信支付开发-微信公众号开发12-微信开发php

    微信公众平台开发之微信支付开发是子恒老师《微信公众平台开发》视频教程的第12部。详细讲解了用php进行微信支付的开发。内容包含获取支付密钥,微信公众号支付开发,扫码支付,微信刷卡支付,异步处理支付结果等等。欢迎反馈,微信/QQ:68183131

    27842 人正在学习 去看看 秦子恒

微信小程序

 

微信网页

 

1. code 用户登录凭证:   

  【作用】

    ①小程序:用于换取用户的openid和本次登录的会话密钥session_key;

    ②微信网页:用于换取access_token的票据,每次用户授权带上的code将不一样,code只能使用一次,5分钟未被使用自动过期。

  【获取途径】

    ① 微信小程序通过wx.login经用户授权获取code;

wx.login({
  success: function(res) {
    let code = res.code; // 微信用户登录凭证,五分钟有效
    /* do something 将code传给后台 */
  },
  fail: function(err) {
    console.log(err);
  }
});

  ② 微信网页通过进入用户授权页面,用户同意后跳转进应用页面,在应用页面url上可获取code(http://***.**.com/?code=dedeuih5455sdwdw5465)

    分两步操作:1) 后台重定向进入引导用户授权页面;2) 如果用户同意授权,跳转页面url将带有code。前端在页面的url上拿参数code

  例如:我们的应用页面是  http://abc.xyz.com/,先进入微信网页授权页面 authorize_url(如下拼接),用户同意授权后,会跳转回我们的应用页面。

/*  
    服务器端[后台开发者] 需要将页面redirect(重定向)至authorize_url 
*/

const AppID = 'wx8af114e3f3*****';
const AppSecret = '255325a19bd769aec********';
const redirect_uri = 'http%3a%2f%2flongfor.ele233.com';   // 注意链接要使用 urlEncode  编码 
const scope = 'snsapi_userinfo';

var authorize_url = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=' + AppID + '&redirect_uri=' + redirect_uri + '&response_type=code&scope=' + scope + '&state=STATE#wechat_redirect'

 

 

2. OpenID 普通用户唯一标志

  【作用】通用户的标识,对当前应用唯一。

  在关注者与公众号产生信息交互后,公众号可获得关注者的openid。特别注意,不同的公众号openid是不同的,不同的小程序openid是不同的,公众号和小程序openid也是不同的,openid只对当前应用是唯一。重要的话说三遍,openid只对当前应用唯一!openid只对当前应用唯一!openid只对当前应用唯一!

  通过openid可以获得用户的基本信息,包括昵称、头像、性别、所在城市、语言和关注时间。小程序接入微信支付也需要openid。

  【获取途径】

    ①微信小程序。后台开发者通过使用 AppId & AppSecret & code 调用 auth.code2Session接口 获得 openid & session_key & unionid (根据情况决定是否返回,已关注或已授权即可返回)

const APPID = '******'
const SECRET = '********'
const JSCODE = '*****'
var authUrl = 'https://api.weixin.qq.com/sns/jscode2session?appid='+APPID+'&secret='+SECRET+'&js_code='+JSCODE+'&grant_type=authorization_code';

  ②微信网页。后台开发者通过使用 AppId & AppSecret & code 调用微信网页的OAuth接口 获得 access_token 和 openid

const AppID = 'wx8af114e3f3*****';
const AppSecret = '255325a19bd769aec********';
let code = req.query.code;  // 客户端传递的code

var getTokenUrl = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid=' + AppID + '&secret=' + AppSecret + '&code=' + code + '&grant_type=authorization_code'

/*
后端需要调用getTokenUrl这个接口来获取access_token和openid。
*/

 

 

3. UnionID 微信用户唯一标志

  【作用】用户唯一标识。前面讲到openid在不同的应用中是不同的,但是开发者拥有多个应用,如何区分用户的唯一性?这时候,unionid就上场了。只要是同一个微信开放平台帐号下的移动应用、网站应用和公众帐号(包括小程序),用户的 UnionID 是唯一的。

  使用前提:使用unionid,需要前往微信开放平台,将这些公众号和应用绑定到一个开放平台账号下,绑定后,一个用户虽然对多个公众号和应用有多个不同的OpenID,但他对所有这些同一开放平台账号下的公众号和应用,只有一个UnionID。

  【获取】

  ① 通过 wx.getUserInfo获取含unionId的加密数据,需要后台开发者进行解密

  ② 用户已关注公众号,wx.login 和 auth.code2Session 可获得返回的unionid

  ③用户已经授权登录过公众号或小程序,wx.login 和 auth.code2Session 可获得返回的unionid

  ④ 支付完成可调用接口getPaidUnionId获取unionid,接口在支付行为的五分钟内有效

 

4. session_key 本地登录的会话密钥

  【作用】通过 wx.getUserInfo获取微信用户数据encryptedData(含手机号码,被加密),后台开发者解密用户数据需要用到session_key

  【获取途径】微信小程序。后台开发者通过使用 AppId & AppSecret & code 调用 auth.code2Session接口 获得 openid & session_key & unionid (根据情况决定是否返回,已关注或已授权即可返回)

 

 

5. access_token 小程序/公众号全局唯一后台接口调用凭据

  【作用】调用绝大多数后台接口时都需使用 access_token。access_token有两种

    ①普通access_token:全局性的,用于调用微信提供的各种接口,作为开发者的调用凭证,有调用次数限制。用access_token和openid获取用户信息需要用户已经关注公众号。

    ②网页授权access_token:用于获取用户的基本信息,

  【获取途径】

  ①微信小程序。后台开发者用 AppId & AppSecret 换取 access_token

  ②微信网页。后台开发者通过使用 AppId & AppSecret & code 调用微信网页的OAuth接口 获得 access_token 和 openid

 

2019-05-28 19:25:20 juan1997 阅读数 567
  • 微信支付开发-微信公众号开发12-微信开发php

    微信公众平台开发之微信支付开发是子恒老师《微信公众平台开发》视频教程的第12部。详细讲解了用php进行微信支付的开发。内容包含获取支付密钥,微信公众号支付开发,扫码支付,微信刷卡支付,异步处理支付结果等等。欢迎反馈,微信/QQ:68183131

    27842 人正在学习 去看看 秦子恒

基于springboot框架的微信公众号基础开发(二)----用户授权和微信公众号登录。
转载需注明:https://blog.csdn.net/juan1997/article/details/90645553

 /**
	 * 一、第一步:用户同意授权,获取code code说明 :
	 * code作为换取access_token的票据,每次用户授权带上的code将不一样,code只能使用一次,5分钟未被使用自动过期。
	 * 
	 * @param returnUrl
	 * @return
	 */
	@GetMapping("/authorize")
	public String authorize(@RequestParam("returnUrl") String returnUrl) {
		// String url = "http://www.lovezhj.cn";
		String url = returnUrl;
		String redirectURL = wxMpService.oauth2buildAuthorizationUrl(url, WxConsts.OAuth2Scope.SNSAPI_USERINFO,
				URLEncoder.encode(returnUrl));
		log.info("【微信网页授权】获取code,redirectURL={}", redirectURL);
		return returnUrl;

	}
/**
	 * 微信公众号登录
	 * 
	 * @param code
	 * @param state
	 * @return
	 * @throws Exception
	 */
	@GetMapping("/login")
	public R login(@RequestParam("code") String code, @RequestParam("state") String state) throws Exception {
		R result = null;
		log.info("【微信网页授权】code={}", code);
		log.info("【微信网页授权】state={}", state);
		WxMpOAuth2AccessToken wxMpOAuth2AccessToken;
		try {
			// 第二步:通过code换取网页授权access_token
			// 网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同
			wxMpOAuth2AccessToken = wxMpService.oauth2getAccessToken(code);
		} catch (WxErrorException e) {
			log.info("【微信网页授权异常】{}", e);
			throw new Exception(e.getError().getErrorMsg());
		}
		// 第三步:刷新token(如果有需要的时候)
		// 第四步: 用oauth2获取用户信息.拉取用户信息(需scope为 snsapi_userinfo)
		WxMpUser wxMpUser = wxMpService.oauth2getUserInfo(wxMpOAuth2AccessToken, null);

		return result;
	}	

App通用时间规则

阅读数 824

没有更多推荐了,返回首页