微信开发五: 网页授权

微信开发文档:http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html


构造到授权的网页链接

使用方式:例


 // new baseservice().BuildAuthCallbackUrl("/mydemo/product/ProductDetails?id="+product.getId(), EnumScopeType.snsapi_userinfo);


package com.star.wxservice;

import java.io.IOException;
import java.io.UnsupportedEncodingException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.star.etmvcfilters.BaseServcie;
import com.star.model.UserSessionUtil;
import com.star.model.Wechat_User;
import com.star.utils.Cache;
import com.star.utils.CacheManager;
import com.star.utils.HttpRequestUtil;
import com.star.utils.JsonMapper;
import com.star.wxmessagemodel.EnumScopeType;
import com.star.wxmessagemodel.OpenIdResult;
import com.star.wxmessagemodel.RefreshtokenResult;
import com.star.wxmessagemodel.TokenJsonResult;
import com.star.wxmessagemodel.WechatUserInfo;

import config.Property;

public class baseservice {

    private static Logger logger = Logger.getLogger(baseservice.class);

    private static final String WECHAR_PATH = "/config/wechat.properties";

    public static final String WECHAT_APPID = Property.GetXMLValuesByKey(WECHAR_PATH, "WECHAT_APPID");

    public static final String WECHAT_SECRET = Property.GetXMLValuesByKey(WECHAR_PATH, "WECHAT_SECRET");

    private static final String Web_PATH = "/config/web.properties";

    /**
     * 当前域名
     */
    public static String ServerName = Property.GetXMLValuesByKey(Web_PATH, "ServerName");

    /**
     * 获取每次操作微信API的Token访问令牌
     * 
     * @return <param name="appid">应用ID</param>
     *         <param name="secret">开发者凭据</param>
     * @throws Exception
     */
    public String GetAccessToken() throws Exception {
        String key = "weixin.accesstoken";
        // 正常情况下access_token有效期为7200秒,这里使用缓存设置短于这个时间即可

        String token = "";

        if (CacheManager.getCacheInfo(key) == null) {
            String grant_type = "client_credential";
            String url = "https://api.weixin.qq.com/cgi-bin/token";
            String para = String.format("grant_type=%s&appid=%s&secret=%s", grant_type, WECHAT_APPID, WECHAT_SECRET);
            String jsonStr = HttpRequestUtil.sendGet(url, para);
            TokenJsonResult jsonObject = JsonMapper.json2Bean(jsonStr, TokenJsonResult.class);

            Cache cache = new Cache();
            cache.setKey("accesstoken");
            cache.setValue(jsonObject.getAccess_token());
            cache.setTimeOut(7000);
            cache.setExpired(false);

            CacheManager.putCache(key, cache);

            return jsonObject.getAccess_token();
        } else {
            return CacheManager.getCacheInfo(key).getValue().toString();
        }
    }

    /**
     * 获取openId
     * 
     * @param code
     * @return
     * @throws Exception
     */
    public OpenIdResult GetOpenId(String code) throws Exception {
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token";
        String para = String.format("appid=%s&secret=%s&code=%s&grant_type=authorization_code", WECHAT_APPID,
                WECHAT_SECRET, code);
        String jsonStr = HttpRequestUtil.sendGet(url, para);

        OpenIdResult result = JsonMapper.json2Bean(jsonStr, OpenIdResult.class);

        return result;
    }

    /**
     * 获取微信用户基本信息 -静默授权
     * 
     * @param openId
     * @return
     * @throws Exception
     */
    public WechatUserInfo GetUserInfo(String openId) throws Exception {
        logger.error("OPENID=============================================" + openId);

        String url = "https://api.weixin.qq.com/cgi-bin/user/info";
        String para = String.format("access_token=%s&openid=%s&lang=zh_CN", GetAccessToken(), openId);
        String jsonStr = HttpRequestUtil.sendGet(url, para);
        // jsonStr = new String(jsonStr.getBytes("ISO-8859-1"), "UTF-8");
        logger.error("OPENID---jsonStr  =============================================" + jsonStr);
        WechatUserInfo model = JsonMapper.json2Bean(jsonStr, WechatUserInfo.class);
        return model;
    }

    /// <summary>
    /// 构造URL
    /// </summary>
    /// <param name="pathAndQuery"></param>
    /// <returns></returns>
    public String GetUrl(String pathAndQuery) {
        return String.format("%s%s", ServerName, pathAndQuery);// pathAndQuery.TrimStart('/')
    }

    /**
     * 构造微信通用授权URL
     * 
     * @param redirectUrl
     *            授权后跳转的页面
     * @param state
     *            自定义函数
     * @param scope
     *            授权类型 :snsapi_base 静默授权, snsapi_userinfo手动同意授权
     * @return
     */
    public String BuildAuthUrl(String redirectUrl, String state, String scope) {
        String apiUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s#wechat_redirect";
        try {
            redirectUrl = java.net.URLEncoder.encode(redirectUrl, "utf-8");
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return String.format(apiUrl, WECHAT_APPID, redirectUrl, scope, state);
    }

    /**
     * 构造授权回调地址
     * 
     * @param type
     *            页面类型
     * @param scope
     *            授权类型 :snsapi_base 静默授权, snsapi_userinfo手动同意授权
     * @return
     */
    public String BuildAuthCallbackUrl(String returnUrl, EnumScopeType scope) {
        String url = BuildAuthUrl(GetUrl(String.format("/yeewii.m/WXApi/Auth?action=%s", returnUrl)), "state",
                scope.toString());// Guid.NewGuid().ToString().Replace("-",
        System.out.println("============================="); // "") // //
        System.out.println(url); // "")
        return url;
    }

    /// <summary>
    /// 登录,若用户存在,则返回登录后的用户信息,否则返回null
    /// </summary>
    /// <param name="openId"></param>
    /// <returns></returns>
    public Wechat_User LoginInternal(HttpServletRequest request, HttpServletResponse response, String openId,
            WechatUserInfo wxUser) throws Exception {

        UserSessionUtil session = new UserSessionUtil();
        session.setHeadimgurl(wxUser != null ? wxUser.headimgurl : "");
        session.setNickname(wxUser != null ? wxUser.nickname : "");
        session.setOpenId(wxUser != null ? wxUser.openid : "");

        request.getSession().setAttribute("wxUser", session);

        Wechat_User webchatuser = Wechat_User.findFirst(Wechat_User.class, "openid=?", new Object[] { openId });
        if (webchatuser != null) {
            BaseServcie.sendAutoLoginCookie(request, response, webchatuser);
        }
        return webchatuser;
    }

    /**
     * 刷新access_token(如果需要)
     * 
     * @param refresh_token
     * @return
     * @throws JsonParseException
     * @throws JsonMappingException
     * @throws IOException
     */
    public RefreshtokenResult Refreshtoken(String refresh_token)
            throws JsonParseException, JsonMappingException, IOException {
        String url = "https://api.weixin.qq.com/sns/oauth2/refresh_token";
        String para = String.format("appid=%s&grant_type=refresh_token&refresh_token=%s", WECHAT_APPID, refresh_token);
        String jsonStr = HttpRequestUtil.sendGet(url, para);

        RefreshtokenResult result = JsonMapper.json2Bean(jsonStr, RefreshtokenResult.class);
        return result;
    }

    /**
     * 获取微信用户基本信息 -手动授权
     * 
     * @param openId
     * @param accessToken
     * @param refresh_token
     * @return
     * @throws Exception
     * @throws JsonMappingException
     * @throws IOException
     */
    public WechatUserInfo GetSnsapiUserinfo(String openId, String accessToken, String refresh_token)
            throws Exception, JsonMappingException, IOException {
        String url = "https://api.weixin.qq.com/sns/userinfo";
        RefreshtokenResult toRefreshtokenResult = Refreshtoken(refresh_token);

        String para = String.format("access_token=%s&openid=%s&lang=zh_CN", accessToken, openId);
        String jsonStr = HttpRequestUtil.sendGet(url, para);
        WechatUserInfo result = JsonMapper.json2Bean(jsonStr, WechatUserInfo.class);
        return result;
        // 在获取用户信息时,提示,"errcode": 48001, 接口未被授权
        // 需要用户提升为服务号,并且进行认证缴交每年300元
    }

    /**
     * 最底层字符串编码转换的实现方法
     * 
     * @param str
     *            待转换的字符串
     * @param oldCharset
     *            源字符集
     * @param newCharset
     *            目标字符集
     * @return 转换后的字符串
     */
    public String changeCharset(String str, String oldCharset, String newCharset) {
        if (str != null) {
            // 用源字符编码解码字符串
            try {
                return new String(str.getBytes(oldCharset), newCharset);
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

}


相关转换实体类

package com.star.wxmessagemodel;

public enum EnumScopeType {

    /**
     * 静默授权
     */
    snsapi_base,

    /**
     * 需手动同意授权
     */
    snsapi_userinfo,

}


package com.star.wxmessagemodel;

public class OpenIdResult {

    public String access_token;

    public String getAccess_token() {
        return access_token;
    }

    public void setAccess_token(String access_token) {
        this.access_token = access_token;
    }

    public String getExpires_in() {
        return expires_in;
    }

    public void setExpires_in(String expires_in) {
        this.expires_in = expires_in;
    }

    public String getRefresh_token() {
        return refresh_token;
    }

    public void setRefresh_token(String refresh_token) {
        this.refresh_token = refresh_token;
    }

    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;
    }

    public String getErrcode() {
        return errcode;
    }

    public void setErrcode(String errcode) {
        this.errcode = errcode;
    }

    public String getErrmsg() {
        return errmsg;
    }

    public void setErrmsg(String errmsg) {
        this.errmsg = errmsg;
    }

    public String expires_in;

    public String refresh_token;

    public String openid;

    public String scope;

    public String errcode;

    public String errmsg;

    public String unionid;

    public String getUnionid() {
        return unionid;
    }

    public void setUnionid(String unionid) {
        this.unionid = unionid;
    }

}

package com.star.wxmessagemodel;

/**
 * 刷新access_token(如果需要)
 * 由于access_token拥有较短的有效期,当access_token超时后,可以使用refresh_token进行刷新,refresh_token拥有较长的有效期(7天、30天、60天、90天),当refresh_token失效的后,需要用户重新授权。
 * 
 * @author Administrator
 *
 */
public class RefreshtokenResult {

    public String access_token;

    public String getAccess_token() {
        return access_token;
    }

    public void setAccess_token(String access_token) {
        this.access_token = access_token;
    }

    public String getExpires_in() {
        return expires_in;
    }

    public void setExpires_in(String expires_in) {
        this.expires_in = expires_in;
    }

    public String getRefresh_token() {
        return refresh_token;
    }

    public void setRefresh_token(String refresh_token) {
        this.refresh_token = refresh_token;
    }

    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;
    }

    public String expires_in;

    public String refresh_token;

    public String openid;

    public String scope;

}

package com.star.wxmessagemodel;

public class TicketResult {

    public String errcode;

    public String getErrcode() {
        return errcode;
    }

    public void setErrcode(String errcode) {
        this.errcode = errcode;
    }

    public String getErrmsg() {
        return errmsg;
    }

    public void setErrmsg(String errmsg) {
        this.errmsg = errmsg;
    }

    public String getTicket() {
        return ticket;
    }

    public void setTicket(String ticket) {
        this.ticket = ticket;
    }

    public String getExpires_in() {
        return expires_in;
    }

    public void setExpires_in(String expires_in) {
        this.expires_in = expires_in;
    }

    public String errmsg;

    public String ticket;

    public String expires_in;
}


package com.star.wxmessagemodel;

public class TokenJsonResult {

    public String access_token;

    public String getAccess_token() {
        return access_token;
    }

    public void setAccess_token(String access_token) {
        this.access_token = access_token;
    }

    public String getExpires_in() {
        return expires_in;
    }

    public void setExpires_in(String expires_in) {
        this.expires_in = expires_in;
    }

    public String getErrcode() {
        return errcode;
    }

    public void setErrcode(String errcode) {
        this.errcode = errcode;
    }

    public String getErrmsg() {
        return errmsg;
    }

    public void setErrmsg(String errmsg) {
        this.errmsg = errmsg;
    }

    public String expires_in;

    public String errcode;

    public String errmsg;

}

cache

package com.star.utils;

public class Cache {
    private String key;// 缓存ID

    private Object value;// 缓存数据

    private long timeOut;// 更新时间

    private boolean expired; // 是否终止

    public Cache() {
        super();
    }

    public Cache(String key, Object value, long timeOut, boolean expired) {
        this.key = key;
        this.value = value;
        this.timeOut = timeOut;
        this.expired = expired;
    }

    public String getKey() {
        return key;
    }

    public long getTimeOut() {
        return timeOut;
    }

    public Object getValue() {
        return value;
    }

    public void setKey(String string) {
        key = string;
    }

    public void setTimeOut(long l) {
        timeOut = l;
    }

    public void setValue(Object object) {
        value = object;
    }

    public boolean isExpired() {
        return expired;
    }

    public void setExpired(boolean b) {
        expired = b;
    }
}


回调地址 (获取用户信息) 返回到指定页面

/**
     * 回调地址 (登录操作,获取用户信息) 返回到指定页面
     * 
     * @param code
     * @param state
     * @return
     * @throws Exception
     */
    public JspView Auth(String code, String state) throws Exception {
        String targetUrl = "";
        Wechat_User user = new Wechat_User();
        String openId = "";
        try {
            targetUrl = request.getParameter("action");

            // String actionValue = request.getParameter("action");

            // // 也可以这样判断 是否在其中
            // //
            // Arrays.asList(EnumWechatMenuType.values()).contains(actionValue);
            // if (!EnumWechatMenuType.IsIndexfoNo(actionValue)) {
            // // String.format("微信授权回调错误,未知的动作:{0}.", actionValue)
            // }

            baseservice baseService = new baseservice();
            OpenIdResult openresult = baseService.GetOpenId(code);
            openId = openresult.getOpenid();
            String accessToken = openresult.getAccess_token();
            String refresh_token = openresult.getRefresh_token();

            // WechatUserInfo wxUser = baseService.GetUserInfo(openId);//
            // //
            // 以snsapi_base为scope发起的网页授权,是用来获取进入页面的用户的openid的,并且是静默授权并自动跳转到回调页的。用户感知的就是直接进入了回调页(往往是业务页面)

            WechatUserInfo wxUser = baseService.GetSnsapiUserinfo(openId, accessToken, refresh_token);
            //
            // 以snsapi_userinfo为scope发起的网页授权,是用来获取用户的基本信息的。但这种授权需要用户手动同意,并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息。
            user = baseService.LoginInternal(request, response, openId, wxUser);

            // for (EnumWechatMenuType name : EnumWechatMenuType.values()) {
            // if (name.toString().equals(actionValue)) {
            // targetUrl = name.getReturnurl();
            // break;
            // }
            // }
            if (user == null) {
                Map<String, Object> map = new Wechat_UserDao().do_Wechatreg(request, response, openId, wxUser.nickname,
                        wxUser.headimgurl, "", "");
                if (!map.get("result").equals(true) && !map.get("result").equals("true")) {
                    // 做失败操作
                    logger.error("回调地址 (登录操作,获取用户信息) 返回到指定页面==获取用户信息失败");
                }
            }
        } catch (Exception ex) {
            // 异常操作
            logger.error("回调地址 (登录操作,获取用户信息) 返回到指定页面==获取用户信息异常" + ex);
        }

        redirect(targetUrl);
        JspView view = new JspView(targetUrl);
        view.setAttribute("user", user);
        return view;
    }




评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值