一.微信授权认证

如果用户在微信客户端中访问第三方网页,公众号可以通过微信网页授权机制,来获取用户基本信息,进而实现业务逻辑。

关于网页授权的两种scope的区别说明

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

2、以snsapi_userinfo为scope发起的网页授权,是用来获取用户的基本信息的。但这种授权需要用户手动同意,并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息。

3、用户管理类接口中的“获取用户基本信息接口”,是在用户和公众号产生消息交互或关注后事件推送后,才能根据用户OpenID来获取用户基本信息。这个接口,包括其他微信接口,都是需要该用户(即openid)关注了公众号后,才能调用成功的。

关于网页授权access_token和普通access_token的区别

1、微信网页授权是通过OAuth2.0机制实现的,在用户授权给公众号后,公众号可以获取到一个网页授权特有的接口调用凭证(网页授权access_token),通过网页授权access_token可以进行授权后接口调用,如获取用户基本信息;

2、其他微信接口,需要通过基础支持中的“获取access_token”接口来获取到的普通access_token调用。

关于特殊场景下的静默授权

1、上面已经提到,对于以snsapi_base为scope的网页授权,就静默授权的,用户无感知;

2、对于已关注公众号的用户,如果用户从公众号的会话或者自定义菜单进入本公众号的网页授权页,即使是scope为snsapi_userinfo,也是静默授权,用户无感知。

具体而言,网页授权流程分为四步:

1、引导用户进入授权页面同意授权,获取code

2、通过code换取网页授权access_token(与基础支持中的access_token不同)

3、如果需要,开发者可以刷新网页授权access_token,避免过期

4、通过网页授权access_token和openid获取用户基本信息(支持UnionID机制)

以上摘自官方开发文档。点击这里查看。

个人理解就是一旦用户在微信公众平台上进行第三方页面跳转,均会触发认证。如在公众号内通过点击菜单跳转网页(此情况一般在创建菜单对应的url就会引导如下地址)或者是

在点击图文消息时(需要设置对应的url)。

此时开发者需要引导用户打开如下地址来获取code

https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect 若提示“该链接无法访问”,请检查参数是否填写错误,是否拥有scope参数对应的授权作用域权限。 

如需要页面跳转则可通过设置此处的 redirect_uri 来实现。

下面是通过回调的方式,让腾讯回调我们自己的控制器来获取所需要的信息。

通过code获取openid

@RequestMapping(value="/authRedirect.do",method = RequestMethod.GET)
public Object authRedirect(@RequestParam(required = true) String state,Model model,
@RequestParam(required = true) String code, HttpServletRequest request, HttpServletResponse response,
RedirectAttributes redirectAttributes) throws Exception {
String redirectUrl="";
logger.info("---------------微信授权成功回调开始--------------");
try {
if (StringUtils.isNotBlank(code)) {
String oauth_access_token_url = this.wxPropertiesBean.getProperties("wxpt").getProperty("oauth_access_token_url");
String sysytemAppid = (String) wxPropertiesBean.getProperties("system").get("system_appid");
Map config = this.wxMpService.queryWxAccountByCode(sysytemAppid);
Map<String,Object> urlParams = new HashMap<String,Object>();
urlParams.put("appid", config.get("account_appid"));
urlParams.put("secret", config.get("account_appsecret"));
urlParams.put("code", code); String url = HttpUtil.getUrl(oauth_access_token_url, urlParams);
WxApiResult apiResult = HttpUtil.httpsRequest(url, "GET", null);
Map result = HttpUtil.getCommonResult(apiResult);
String openid = (String) result.get("openid");
if(StringUtils.isNotBlank(openid)){
request.getSession().setAttribute("openid", openid); }
}
//查询自定义菜单信息
Map channel = this.wxMpService.queryWxChannelByCode(state);
String relaPath = this.wxPropertiesBean.getProperties("system").getProperty(state);
if(channel!=null&&channel.get("link_url")!=null){
redirectUrl = (String) channel.get("link_url");
}else if(relaPath!=null){
String protocol = (String) config.get("protocol");
String domain = (String) config.get("domain");
redirectUrl = protocol + domain + relaPath;
}else{
String protocol = (String) config.get("protocol");
String domain = (String) config.get("domain");
redirectUrl = protocol + domain;
}
if(redirectUrl.indexOf("?") > -1) {
redirectUrl = redirectUrl +"&v="+Math.random();
}else{
redirectUrl = redirectUrl +"?v="+Math.random();
} }
} catch (Exception e) {
logger.error(e.getMessage());
throw new Exception("系统无法完成请求,错误信息:"+e.getMessage());
} return "redirect:" + redirectUrl;
}
/**
* 发送https请求
* @param requestUrl 请求地址
* @param requestMethod 请求方式(GET、POST)
* @param outputStr 提交的数据
* @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
*/
public static WxApiResult httpsRequest(String requestUrl, String requestMethod, String outputStr) {
WxApiResult message = new WxApiResult();
try {
TrustManager[] tm = { new MyX509TrustManager() };
SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
sslContext.init(null, tm, new java.security.SecureRandom());
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);
conn.setRequestMethod(requestMethod); 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);
}
if(conn.getResponseCode()==conn.HTTP_OK){
message.setCode(0);
message.setContent(buffer.toString());
}else{
message.setCode(-1);
message.setContent("获取返回状态不对,返回状态为:"+conn.getResponseCode());
} // 释放资源
bufferedReader.close();
inputStreamReader.close();
inputStream.close();
inputStream = null;
conn.disconnect(); } catch (ConnectException ce) {
log.error("连接超时:{}", ce);
message.setCode(-1);
message.setContent(ce.getMessage());
} catch (Exception e) {
log.error("https请求异常:{}", e);
message.setCode(-1);
message.setContent(e.getMessage());
}
return message;
}

如需获取用户信息只需通过上述代码中获取到的openid和access_token获取即可。

@Override
public String getCustImg(HttpServletRequest request, Map<String, Object> param){
try{
String openid = (String) request.getSession().getAttribute("openid");
String oauth_access_token_url = "https://api.weixin.qq.com/sns/userinfo";
String accessToken = wxTokenComp.getAccessToken();
Map urlParams = new HashMap();
urlParams.put("openid",openid);
urlParams.put("access_token",accessToken);
urlParams.put("lang","zh_CN"); String url = HttpUtil.getUrl(oauth_access_token_url, urlParams);
WxApiResult apiResult = HttpUtil.httpsRequest(url, "GET", null);
Map rstMap = HttpUtil.getCommonResult(apiResult); }catch(Exception e){
e.printStackTrace();
}
return rstMap.get("headimgurl");
 }

微信公众平台开发教程(三)_OAuth2.0认证的更多相关文章

  1. Senparc.Weixin.MP SDK 微信公众平台开发教程(三):微信公众平台开发验证

    要对接微信公众平台的"开发模式",即对接到自己的网站程序,必须在注册成功之后(见Senparc.Weixin.MP SDK 微信公众平台开发教程(一):微信公众平台注册),等待官方 ...

  2. Senparc.Weixin.MP SDK 微信公众平台开发教程(十二):OAuth2.0说明

    紧接上一篇<Senparc.Weixin.MP SDK 微信公众平台开发教程(十一):高级接口说明>,这里专讲OAuth2.0. 理解OAuth2.0 首先我们通过一张图片来了解一下OAu ...

  3. Senparc.Weixin.MP SDK 微信公众平台开发教程(二十二):在 .NET Core 2.0/3.0 中使用 MessageHandler 中间件

    概述 在 <Senparc.Weixin.MP SDK 微信公众平台开发教程(六):了解MessageHandler> 中我们已经了解了 MessageHandler 的运行原理和使用方法 ...

  4. Senparc.Weixin.MP SDK 微信公众平台开发教程(十八):Web代理功能

    在Senparc.Weixin.dll v4.5.7版本开始,我们提供了Web代理功能,以方便在受限制的局域网内的应用可以顺利调用接口. 有关的修改都在Senparc.Weixin/Utilities ...

  5. Senparc.Weixin.MP SDK 微信公众平台开发教程(十七):个性化菜单接口说明

    前不久微信上线了个性化菜单接口,Senparc.Weixin SDK也已经同步更新. 本次更新升级Senparc.Weixin.MP版本到v13.5.2,依赖Senparc.Weixin版本4.5.4 ...

  6. Senparc.Weixin.MP SDK 微信公众平台开发教程(四):Hello World

    =============  以下写于2013-07-20 ============= 这一篇文章其实可以写在很前面,不过我还是希望开发者们尽多地了解清楚原理之后再下手. 通过上一篇Senparc.W ...

  7. Senparc.Weixin.MP SDK 微信公众平台开发教程(五):使用Senparc.Weixin.MP SDK

    Senparc.Weixin.MP SDK已经涵盖了微信6.x的所有公共API. 整个项目的源代码以及已经编译好的程序集可以在这个项目中获取到:https://github.com/JeffreySu ...

  8. Senparc.Weixin.MP SDK 微信公众平台开发教程(六):了解MessageHandler

    上一篇<Senparc.Weixin.MP SDK 微信公众平台开发教程(五):使用Senparc.Weixin.MP SDK>我们讲述了如何使用Senparc.Weixin.MP SDK ...

  9. Senparc.Weixin.MP SDK 微信公众平台开发教程(七):解决用户上下文(Session)问题

    从这篇文章中我们已经了解了微信公众平台消息传递的方式,这种方式有一个先天的缺陷:不同用户的请求都来自同一个微信服务器,这使得常规的Session无法使用(始终面对同一个请求对象,况且还有对方服务器Co ...

  10. Senparc.Weixin.MP SDK 微信公众平台开发教程(八):通用接口说明

    一.基础说明 这里说的“通用接口(CommonAPIs)”是使用微信公众账号一系列高级功能的必备验证功能(应用于开发模式). 我们通过微信后台唯一的凭证,向通用接口发出请求,得到访问令牌(Access ...

随机推荐

  1. 基于Python & Opencv 图像-视频-处理算法

    Alg1:图像数据格式之间相互转换.png to .jpg(其他的请举一反三) import cv2 import glob def png2jpg(): images = glob.glob('*. ...

  2. 推荐常用的移动端、PC端、小程序的UI框架

    1.移动端UI库 ①.Vant UI 官方地址:https://youzan.github.io/vant/#/zh-CN/intro github地址:https://github.com/youz ...

  3. C# 数据为空,不能对NULL调用此方法或属性的解决办法

    在运行C#项目时,报出了以下错误,错误原因是数据库中的值为null时,查询时会触发该错误提示 部分源代码如下: public List<Student> findData2() { ; / ...

  4. webpack报错需要合适的loader

    以前做vue项目都好好的,最近做react,公共配置感觉加个jsx就可以了吧,然而不是这样的. 一.问题描述 You may need an appropriate loader to handle ...

  5. ruby配合gem使用sass

    Ruby环境安装 1.Ruby安装包下载地址:http://rubyinstaller.org/downloads/下载对应系统版本的安装包: 2.双击rubyinstaller-2.2.3-x64. ...

  6. 【BZOJ4842】[Neerc2016]Delight for a Cat 线性规划+费用流

    [BZOJ4842][Neerc2016]Delight for a Cat Description ls是一个特别堕落的小朋友,对于n个连续的小时,他将要么睡觉要么打隔膜,一个小时内他不能既睡觉也打 ...

  7. react-native flatlist 上拉加载onEndReached方法频繁触发的问题

    问题 在写flatlist复用组件时,调用的时候如果父组件是不定高的组件,会造成组件无法显示 如果父组件样式{flex:1},则会出现下拉方法频繁触发或不正常触发的问题(我这里出现的问题是在列表第6个 ...

  8. (91)Wangdao.com第二十四天_Mutation Observer API 突变监视器

    Mutation Observer API 突变监视接口 用来监视 DOM 变动. DOM 的任何变动,比如节点的增减.属性的变动.文本内容的变动,这个 API 都可以得到通知 概念上,它很接近事件, ...

  9. 解析CommandMessage

    Json 解析: void CommandMessage::ParseCmdBody() { try { Json::Reader reader; Json::Value root; if (!rea ...

  10. js高级4

    1.Date  类 getDate()返回一个月中的某一天 1-31 getDay() 返回一周中的某一天0-6 getFullyear()返回四位数的年份 getMonth()返回月份 比实际情况小 ...