首先我们要清楚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拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息)
相关推荐
代码是用asp独立完成编写的,已成功运用在微信活动项目中,编写过程中搜不到具体的案例...之前放出过一个版本,较之前的版本,这次新增了缓存access_token到数据库的功能,避免在获取用户信息时重复获取access_token
本主题将深入探讨如何在ASP(Active Server Pages)环境中利用OAuth2.0接口实现微信登录,并获取用户的OpenId、Access_Token以及个人资料如头像、昵称和性别等信息。 首先,OAuth2.0是授权框架,它允许第三方应用在...
token(与基础支持中的access_token不同)3、如果需要,开发者可以刷新网页授权access_token,避免过期4、通过网页授权access_token和openid获取用户基本信息(支持UnionID机制)PHP获取微信公众号网页授权和用户...
2. **获取openid**:收到code后,你需要向微信API发送POST请求,换取access_token和openid。这通常在回调函数中完成。代码如下: ```php function get_access_token_and_openid($code) { $url = ...
运用于实际项目中,完善后可将获取到的全局access_token缓存到数据库并判断是否需要更新,再获取用户头像、昵称、是否关注等等信息,可解决access_token重复获取的问题
代码实现将获取到的全局access_token缓存到数据库并判断是否需要重新获取,以解决access_token重复获取超过2000次上限的问题出现。而后再用access_token获取昵称、头像、是否关注等用户信息并存于cookies中
根据appid和app密钥获取access_token,openid等信息
微信OAuth2.0接口是微信官方提供的一种身份验证机制,允许第三方应用在用户授权的情况下获取其微信账号的相关信息,如OpenId、Access_Token、头像、昵称和性别等。这种接口通常用于实现微信登录功能,使得用户可以...
snsapi_base只能获取access_token和openID snsapi_userinfo可以获取更详细的用户资料,比如头像、昵称、性别等 首先,这里的access_token与基础access_token(比如自定义菜单用到的)是不一样的。两者区别如下: 网页...
接着,我们使用access_token和openid,通过微信的接口获取用户基本信息。这通常包括昵称、头像、性别、城市等。需要注意的是,这些信息可能需要用户额外的权限授权才能获取。 在实现文档中,应该详细列出以下步骤:...
5. **微信开发环境配置**:开发者需要在微信开发者平台上创建项目,绑定服务器域名,设置好回调URL,获取必要的凭证(如access_token,jsapi_ticket)等,确保微信服务器能够与项目服务器正常通信。 6. **微信OAuth...
token(与基础支持中的access_token不同)3、如果需要,开发者可以刷新网页授权access_token,避免过期4、通过网页授权access_token和openid获取用户基本信息(支持UnionID机制)jsp获取微信公众号网页授权和用户...
- 在Servlet中处理授权流程,接收回调URL的code,然后调用微信API获取access_token和openid。 - 将获取到的用户信息保存到session或数据库,或者直接返回到jsp页面展示。 - 在jsp页面上,可以通过session或后台...
token、openid等)01-asp获取微信公众号网页授权和用户信息演示02-asp获取远程网页内容03-官方文档概要04-获取用户同意授权05-拿到code后获取返回信息06-获取access_token内容07-获取微信用户openid数
微信网页授权是微信开放平台提供的一种接口,用于实现用户在第三方网站或应用上的一键登录,以及获取用户的微信基本信息。这个过程涉及到OAuth2.0授权框架,它为安全地获取用户信息提供了标准化流程。 首先,我们要...
主要介绍了微信公众号平台接口开发 获取access_token过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
3. 使用Access Token获取用户信息:微信开放平台会返回一个包含access_token、openid等信息的JSON字符串。利用access_token,服务器可以进一步请求用户的基本信息(如通过`sns/userinfo`接口,需确保在创建应用时...
1 微信开放平台:https://open.weixin.qq.com/ 2 微信官方教程:...第三步:通过access_token调用接口 第4步:获取用户个人信息(UnionID机制) api:核
回调URL是用户授权后微信服务器会发送code的地址,用于获取access_token和openid。 3. 配置授权目录 在应用设置中,需要配置授权目录,这是用户点击微信登录按钮后跳转的页面,通常包含微信OAuth2.0的授权请求。 4...
3. 应用接收到code后,使用AppID、AppSecret和code向微信服务器请求access_token和openid。openid是微信用户在全球范围内的唯一标识。 4. 有了access_token和openid,我们可以进一步获取用户的基本信息,如昵称、...