微信授权登录
2017-08-18 15:24
232 查看
微信网页授权登陆,官方文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842
一、创建授权URL
例子:
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
其中state参数,微信会在用户授权之后,回调时,返回给我们的。这个参数很重要,一般需要确保该参数是唯一的(我使用了UUID)
其它参数含义,参照官方文档。
由于该授权链接太长,生成的二维码很密集,这会导致扫码响应时间边长,特别是性能不好的手机。
所以在这里建议将长链接转成短链接。
可以调用微信的接口(长链接转短链接接口),
长链接转短链接接口微信官方文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1443433600
生成短链接后,我将短链接和state参数一起返回给前端
前端用短链接生成二维码,
state参数用于页面的轮询
具体代码:
微信回调之后会返回code,state(我们传过去的参数)
用code换取access_token相关信息,包括用户的openId
用state从数据库获取state相关信息,并将openId存放进去
(之后轮询调用接口时,state记录中有无openId将作为用户是否已经授权登录的依据)
微信回调函数
三、页面轮询
/**
* 校验state(页面轮询调用 for user)
*
* @param request
* @return
*/
@RequestMapping(value = "")
public String checkedState(HttpServletRequest request) {
String state = request.getParameter("state");
try {
// 根据state获取state相关信息
Map<String, Object> data = weChatStateService.get(state);
String openId = (String) data.get("openId");
if (StringUtils.isBlank(openId)) {
return JacksonUtil.toBizJson("4001", "未扫码", null);
}
return JacksonUtil.toBizJson("0", "验证通过", data);
} catch (Exception e) {
e.printStackTrace();
return JacksonUtil.toBizJson("1", "系统错误", null);
}
}
一、创建授权URL
例子:
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
其中state参数,微信会在用户授权之后,回调时,返回给我们的。这个参数很重要,一般需要确保该参数是唯一的(我使用了UUID)
其它参数含义,参照官方文档。
由于该授权链接太长,生成的二维码很密集,这会导致扫码响应时间边长,特别是性能不好的手机。
所以在这里建议将长链接转成短链接。
可以调用微信的接口(长链接转短链接接口),
长链接转短链接接口微信官方文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1443433600
生成短链接后,我将短链接和state参数一起返回给前端
前端用短链接生成二维码,
state参数用于页面的轮询
具体代码:
// 公众号的唯一标识 private static String APP_ID = ""; // 用户同意授权URL(对urlEncode之后) private static String REDIRECT_URL = ""; // 用户同意授权URL private static String AUTHORIZATION_URL = "https://open.weixin.qq.com/connect/oauth2/authorize"; /** * 创建授权URL * * @param commontoken 微信普通token * @param state * @return * @throws Exception */ public Map<String, String> createAuthorizationURL(String commontoken, String state) throws Exception { // 微信用户登录授权URL String longUrl = AUTHORIZATION_URL +"?appid=" + APP_ID + "&redirect_uri=" + REDIRECT_URL + "&response_type=code&scope=snsapi_userinfo&state=" + state + "#wechat_redirect"; // 请求路径(将长链接转成短链接) String url = "https://api.weixin.qq.com/cgi-bin/shorturl?access_token=" + commontoken; // json参数 JSONObject jsonParam = new JSONObject(); jsonParam.put("action", "long2short"); jsonParam.put("long_url", longUrl); // 请求参数 String param = jsonParam.toString(); // 发送请求并获取结果(将长链接转成短链接) String result = SendHttpRequest.sendPostRequest(url, param); if (!result.contains("short_url")) { throw new Exception(result); } // 转成json JSONObject json = JSONObject.parseObject(result); // 保存state Map<String, Object> data = new HashMap<String, Object>(); data.put("state", state); data.put("expiredTime", (System.currentTimeMillis() + 300000)); // state过期时间 // 保存state // 注:由于本人没有接触过redis,再加上项目紧,来不及现学 // 所以我这一步是将state存放在了数据库里, // 个人建议最好存放在缓存中(当然主要还是要根据项目来) weChatStateDao.add(data); // 返回值 Map<String, String> resultMap = new HashMap<String, String>(); resultMap.put("state", state); resultMap.put("shortURL", json.getString("short_url")); return resultMap; }二、通过code换取网页授权access_token
微信回调之后会返回code,state(我们传过去的参数)
用code换取access_token相关信息,包括用户的openId
用state从数据库获取state相关信息,并将openId存放进去
(之后轮询调用接口时,state记录中有无openId将作为用户是否已经授权登录的依据)
微信回调函数
/** * 获取授权认证(for user) * (用户扫码之后,微信会调用该接口,并传递2个参数code,state) * code 用于换取特殊(access_token,该token可以获取用户相关信息) * state 用于验证 * * @param request * @return */ @RequestMapping(value = "") public void getAuthorization(HttpServletRequest request, HttpServletResponse response) { // 获取微信授权端返回的code String code = request.getParameter("code"); // 获取微信授权端返回的status String state = request.getParameter("state"); try { // 根据state获取state相关信息 Map<String, Object> entity = authenticationService.getState(state); if(entity == null) { throw new Exception("状态码不存"); } // 获取过期时间 Long expiredTime = (Long) entity.get("expiredTime"); if (expiredTime < System.currentTimeMillis()) { throw new Exception("状态码已过期"); } // 用code换取access_token相关信息 JSONObject tokenJson = authenticationService.getAccessToken(code); // access_token String accessToken = (String) tokenJson.get("access_token"); // 用户唯一标识 String openId = (String) tokenJson.get("openid"); // 更新state entity.put("openId", openId); authenticationService.updateState(entity); // 根据openid获取用户信息,判断用户是否注册过 UserInfo userInfo = userInfoService.getByOpenId(openId); // 如果用户未注册过,则新增 if (userInfo == null) { userInfo = new UserInfoVo(); // 拉取用户信息 JSONObject userInfoJson = authenticationService.getUserInfo(accessToken, openId); String nickName = userInfoJson.getString("nickname"); // 昵称 (这里需要处理带有表情的昵称,否则可能会导致无法存入到数据库) String headImgUrl = userInfoJson.getString("headimgurl"); // 头像(如果用户修改了头像,此路径会无效) userInfo.setUserName(nickName); // 设置用户姓名 userInfo.setHeadImage(headImgUrl); // 设置用户头像 userInfo.setWechatOpenId(openId); // 设置openId userInfo.setCreateTime 9f3d (new Date());// 创建时间 userInfoService.add(userInfo); } // 重定向,用户授权之后,微信端的页面显示 response.sendRedirect(""); } catch (Exception e) { e.printStackTrace(); } }
三、页面轮询
/**
* 校验state(页面轮询调用 for user)
*
* @param request
* @return
*/
@RequestMapping(value = "")
public String checkedState(HttpServletRequest request) {
String state = request.getParameter("state");
try {
// 根据state获取state相关信息
Map<String, Object> data = weChatStateService.get(state);
String openId = (String) data.get("openId");
if (StringUtils.isBlank(openId)) {
return JacksonUtil.toBizJson("4001", "未扫码", null);
}
return JacksonUtil.toBizJson("0", "验证通过", data);
} catch (Exception e) {
e.printStackTrace();
return JacksonUtil.toBizJson("1", "系统错误", null);
}
}
相关文章推荐
- Android接入微信SDK之一:发起微信授权登录
- 基于第三方微信授权登录的iOS代码分析
- 类似818tu.c微信小说分销系统设计之多公众号网页授权自动登录源码分享
- springboot微信授权登录
- 微信 静默 授权登录 获取openid 实现方法
- 基于第三方微信授权登录的iOS代码分析
- 微信第三方登录(静默授权和非静默授权)实例步骤
- 微信授权登录实现
- IOS实现微信授权登录
- 基于Swift语言开发微信、QQ和微博的SSO授权登录代码分析
- 基于第三方微信授权登录的iOS代码分析
- .net微信授权登录整理
- 微信公众平台开发——微信授权登录(OAuth2.0)
- 基于第三方微信授权登录的iOS代码分析
- 微信授权登录并获取用户信息接口开发
- 基于第三方微信授权登录的iOS代码分析
- 微信网页授权开发工具报“暂不支持当前URL登录态拼接”问题
- iOS App 友盟授权登录后,如何获取微信unionid
- 微信静默授权登录
- 微信小程序获取手机号授权用户登录功能