java基于微信开发,用oauth2静默授权是,回调的url总是执行两次,怎么回事呀?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java基于微信开发,用oauth2静默授权是,回调的url总是执行两次,怎么回事呀?相关的知识,希望对你有一定的参考价值。

    用户关注微信公众账号;

    微信公众账号提供用户请求授权页面URL;

    用户点击授权页面URL,将向服务器发起请求;

    服务器询问用户是否同意授权给微信公众账号;

    用户同意(scope为snsapi_base时无此步骤);

    服务器将CODE通过回调传给微信公众账号;

    微信公众账号获得CODE;

    微信公众账号通过CODE向服务器请求Access Token;

    服务器返回Access Token和OpenID给微信公众账号;

    微信公众账号通过Access Token向服务器请求用户信息;

    服务器将用户信息回送给微信公众账号。

参考技术A

@RequestMapping("/oauth")

public String oauth(Integer companyId, Integer model, Double latitude, Double longitude, Integer style,

HttpServletRequest request, HttpServletResponse response, HttpSession session)


if (companyId == 54)

style = 1;

else

style = 0;

try

request.setCharacterEncoding("utf8");

response.setCharacterEncoding("utf8");

catch (Exception e)

e.printStackTrace();

// 获取到code

String code = request.getParameter("code");

System.out.println("获取用户OPENID时的CODE:" + code);

if (StringUtils.isEmpty(code))

System.out.println("获取用户OPENID时的CODE为空!");

return null;

if (StringUtils.isEmpty(longitude) || StringUtils.isEmpty(latitude))

longitude = 0.0;

latitude = 0.0;

// 从session中获取openId信息

String openId = (String) session.getAttribute(companyId + "OPENID");

if (StringUtils.isEmpty(openId))

try

// 根据公司id查询出 token appId appSecret

String appId = null;

String appSecret = null;

CompanyInfo companyInfo = companyInfoService.selectByCompanyId(companyId);

if (!StringUtils.isEmpty(companyInfo))

appId = companyInfo.getAppid();

appSecret = companyInfo.getAppsecret();

// 静默授权

String get_access_token_url = "https://api.weixin.qq.com/sns/oauth2/access_token?" + "appid=" + appId

+ "&secret=" + appSecret + "&code=CODE&grant_type=authorization_code";

get_access_token_url = get_access_token_url.replace("CODE", code);

JSONObject json = CommonUtil.httpsRequest(get_access_token_url, "GET", null);

if (StringUtils.isEmpty(json))

System.out.println("从微信服务器新获取的用户OPENID,返回JSON信息为空");

return null;

JSONObject jsonObject = JSONObject.fromObject(json);

try

openId = jsonObject.getString("openid");

session.setAttribute(companyId + "OPENID", openId);// 放入session

System.out.println("新获取的用户OPENID:" + openId);

return "redirect:fitnessService.do?companyId=" + companyId + "&model=" + model + "&openId=" + openId

+ "&latitude=" + latitude + "&longitude=" + longitude + "&style=" + style;

catch (Exception e)

System.out.println("返回JSON信息中获取用户OPENID失败异常");

return null;

catch (Exception e)

e.printStackTrace();

return null;

else

System.out.println("SESSION中的OPENID:" + openId);

return "redirect:fitnessService.do?companyId=" + companyId + "&model=" + model + "&openId=" + openId

+ "&latitude=" + latitude + "&longitude=" + longitude + "&style=" + style;

看看代码思路即可  openID可以缓存  自己研究下吧  

参考技术B 微信访问你的回调地址,你必须给它返回个“SUCCESS”字符串,不然他就会认为你没有接收到信息 参考技术C 我这里也是,请问您解决了么? 参考技术D 微信公众平台OAuth2.0授权详细步骤如下:
1. 用户关注微信公众账号。
2. 微信公众账号提供用户请求授权页面URL。
3. 用户点击授权页面URL,将向服务器发起请求
4. 服务器询问用户是否同意授权给微信公众账号(scope为snsapi_base时无此步骤)
5. 用户同意(scope为snsapi_base时无此步骤)
6. 服务器将CODE通过回调传给微信公众账号
7. 微信公众账号获得CODE
8. 微信公众账号通过CODE向服务器请求Access Token
9. 服务器返回Access Token和OpenID给微信公众账号
10. 微信公众账号通过Access Token向服务器请求用户信息(scope为snsapi_base时无此步骤)
11. 服务器将用户信息回送给微信公众账号(scope为snsapi_base时无此步骤)

微信静默授权问题

微信中需要获取openid,为了安全起见,采用服务器端静默授权方式,最终过程是:

前端页面(获取openid) -> 指定服务器端地址 -> 服务器端跳转到微信授权页 -> 微信授权页跳回服务器端 -> 服务器端跳回前端页面

在这里会存在一个问题,即微信授权返回死循环问题,因为这边前端跳转全部都是使用replace跳转,所以不会在history上再增加1一个页面,后来以为是我们服务器的问题,然后撇开微信直接让服务器端返回一个假的openid发现是可以返回的,所以问题出在微信的授权问题上,即:无论前端跳转是否采用replace,使用微信授权,微信自动会在浏览器增加一条页面,即跳转微信授权前的一个页面,这样的话,当用户点击返回按钮的时候,自然是返回到没有授权页,然后没有授权页根据业务逻辑再继续发起授权请求,就这样陷入了无线循环之中。

也思考过一些解决方式,比如使用iframe来获取openid,比如使用XMLHttpRequest来代替服务器端跳转,这些全部都行不通,所以只能在请求授权页做手脚,即判断 是否应该去获取授权页,如果是因为返回进入该页面的 则执行history.back(),否则则进入微信授权模式,但是这种方式还是存在一个问题,即如果请求授权页本身就是首页怎么办,执行history.back()也不会让微信浏览器自动关闭,这个时候就会卡在这里,当然是可以使用微信JSSDK的closeWindow()方法,但是这种方式需要等待wx.config()完成,这里涉及到从服务器端获取签名等流程,具有明显的延时情况,造成一种很糟糕的用户体验,所以最终的解决方式是:

1:如果请求授权页是首页,当用户点击返回按钮的时候,还是走授权页,即陷入无限循环套路,

2:如果请求授权页不是首页,则执行higtory.back() 返回上一页

 

以上是关于java基于微信开发,用oauth2静默授权是,回调的url总是执行两次,怎么回事呀?的主要内容,如果未能解决你的问题,请参考以下文章

微信静默授权问题

基于SPA的网页授权流程(微信OAuth2)

微信公众号(静默授权和分享)

微信公众号开发 - 静默授权获取用户信息

Java微信公众平台开发之OAuth2.0网页授权

Java微信公众平台开发(十六)--微信网页授权(OAuth2.0授权)获取用户基本信息