多域名下获取微信openId,通过拦截器注解实现,减少代码量以及业务混淆

一个注解,一个拦截器,还有一个中转html页(来源网上,稍微修改),原理看拦截器的类注解。

三个文件的下载链接https://pan.baidu.com/s/1Gt07PVtiKrG1uh2SVJKqSQ

package com.xxx.admin.interceptor;

import com.xxx.core.annotation.GetOpenId;
import com.jfinal.aop.Interceptor;
import com.jfinal.aop.Invocation;
import com.jfinal.weixin.sdk.api.SnsAccessToken;
import com.jfinal.weixin.sdk.api.SnsAccessTokenApi;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.URLEncoder;

/**
 * 模板
 * 多域名获取openid 样例DEMO
 * B.getOpenid(一般是充值页面路由) -->A.GETWXCODE.html-->weixin--> A.GETWXCODE.html?redirect_uri=B.getOpenid&code=XXX --(redirect_uri)--> B.getOpenid?code=XXX
 * http://有页面回调权限的项目域名/GETWXCODE.html?appid=APPID&response_type=code&redirect_uri=Encode(GETWXCODE.html?redirect_uri=当前请求地址)&scope=snsapi_base&state=wx#wechat_redirect
 * 当前请求参数不要用?a=1&b=1传参数,用jfinal的/a-b-c形式传参
 *
 * 获得的openId被存在会话session中,后续接口可以直接获取
 * @author WesleyOne
 * @create 2018/8/19
 */
public class _GetOpenidInterceptor implements Interceptor {

    private static final Logger LOG    = LoggerFactory.getLogger(_GetOpenidInterceptor.class);


    @Override
    public void intercept(Invocation inv) {

        GetOpenId getOpenId = inv.getMethod().getAnnotation(GetOpenId.class);
        if (getOpenId == null) {
            inv.invoke();
            return;
        }
        //会话中已经存在openId就不获取
        if (inv.getController().getSessionAttr("wxopenid")!=null){
            inv.invoke();
            return;
        }
        //不在微信浏览器的也不获取
        String userAgent = inv.getController().getHeader("user-agent");
        boolean isWx = false;
        if (userAgent!=null){
            userAgent = userAgent.toLowerCase();
            if (userAgent.indexOf("micromessenger") > -1){
                isWx = true;
            }
        }
        inv.getController().setAttr("isWx",isWx);
        if (!isWx){
            inv.invoke();
            return;
        }

        // 当前是跳转页面业务逻辑先处理,再获取openId
        inv.invoke();

        String code = inv.getController().getPara("code");
        StringBuffer requestURL = inv.getController().getRequest().getRequestURL();

        // TODO 你的配置项
        String wxAppId = "你的微信APPID";
        String wxAppSecret = "你的微信APPSECRET";
        String domain = "有页面回调权限的项目域名";

        if (code == null){
            LOG.info("获取code url={}",requestURL);
            //拼接当前路由作为回调地址,请求回调中转页
            String redirectdomain = "http://"+domain+"/GETWXCODE.html";
            // 当前路由全名
            String url = redirectdomain+"?appid="+wxAppId+"&scope=snsapi_base&state=STATE&redirect_uri="+URLEncoder.encode(redirectdomain+"?redirect_uri="+requestURL.toString());
            inv.getController().redirect(url,true);
            return;
        }else {
            //获取到了code,以获取openid
            LOG.info("获取到code={} url={}",code,requestURL);
            SnsAccessToken snsAccessToken = SnsAccessTokenApi.getSnsAccessToken(wxAppId, wxAppSecret, code);
            if (snsAccessToken == null||snsAccessToken.getOpenid()==null){
                inv.getController().renderText("非法操作");
                return;
            }
            inv.getController().setSessionAttr("wxopenid",snsAccessToken.getOpenid());
        }
    }

}
package com.xxx.core.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 获取openId
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface GetOpenId {
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>微信登陆</title>
</head>
<body>
<script>
 function getUrlParams(key) {
 var args = {};
 var pairs = location.search.substring(1).split('&');
 for (var i = 0; i < pairs.length; i++) {
 var pos = pairs[i].indexOf('=');
 if (pos === -1) {
 continue;
 }
 args[pairs[i].substring(0, pos)] = decodeURIComponent(pairs[i].substring(pos + 1));
 }
 return args[key];
 }
 function appendParams(params, url) {
 var baseWithSearch = url.split('#')[0];
 var hash = url.split('#')[1];
 for (var i = 0; i < params.length; i++) {
 if (params[i].value !== undefined) {
 var newParam = params[i].key + "=" + params[i].value;
 if (baseWithSearch.indexOf('?') > 0) {
 var oldParamReg = new RegExp(params[i].key + '=[-\\w]{0,40}', 'g');
 if (oldParamReg.test(baseWithSearch)) {
 baseWithSearch = baseWithSearch.replace(oldParamReg, newParam);
 } else {
 baseWithSearch += "&" + newParam;
 }
                } else {
 baseWithSearch += "?" + newParam;
 }
            }
        }
 if (hash) {
 url = baseWithSearch + '#' + hash;
 } else {
 url = baseWithSearch;
 }
 return url;
 }
 var code = getUrlParams('code');
 var appId = getUrlParams('appid');
 var scope = getUrlParams('scope') || 'snsapi_base';
 var state = getUrlParams('state');
 var redirectUrl;
 if (!code) {
 redirectUrl = appendParams([{
 key: 'appid',
 value: appId
 }, {
 key: 'redirect_uri',
 value: encodeURIComponent(location.href)
        }, {
 key: 'response_type',
 value: 'code'
 }, {
 key: 'scope',
 value: scope
 }, {
 key: 'state',
 value: state
 }], 'https://open.weixin.qq.com/connect/oauth2/authorize#wechat_redirect');
 } else {
 redirectUrl = appendParams([{key: 'code', value: code},{
 key: 'state',
 value: state
 }], getUrlParams('redirect_uri'));
 }
 location.href = redirectUrl;
</script>
</body>
</html>


评论区

JFinal

2018-08-19 16:11

@wesleyxw 多域名下获取微信 openId 这个功能还从没有人分享过,在某些场景下很有价值

贴代码有个专用按钮,可以贴出来 html、xml、java 等常见代码格式,注意看可视化编辑器上方的 icon,鼠标停留时会显示功能提示

感谢分享,点赞收藏

wesleyxw

2018-08-20 08:54

@JFinal Thanks♪(・ω・)ノ

leomj

2018-08-20 19:23

very
good

热门分享

扫码入社