微信开发五: 网页授权

    xiaoxiao2021-12-14  18

    微信开发文档: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; }

    转载请注明原文地址: https://ju.6miu.com/read-963249.html

    最新回复(0)