1.获取微信用户信息要调用微信的好几个接口,再加上自己系统的接口就会变的很慢,影响用户体验,之前走过的弯路我就不赘述了,直接说新的方案。

2.第一步都是向微信发起获取用户code请求:

请求接口:https://open.weixin.qq.com/connect/oauth2/authorize

参数:

var backUrl = encodeURIComponent("http://test.yitian.com/api/wechat/authBack?id=123");
//拼接微信网页授权url
var loginUrlx = "https://open.weixin.qq.com/connect/oauth2/authorize?";
var appIdParamx = "appid=wxbc236589746505";
var redirectParamx = "redirect_uri=" + backUrl + "&";
var scopeParamx = "scope=snsapi_userinfo&";
var responseParamx = "response_type=code&";
var stateParamx = "state=" + (document.location.toString());
var endingParamx = "#wechat_redirect";
//最终拼接后的授权url
var lastUrlx = loginUrlx + appIdParamx + redirectParamx + scopeParamx + responseParamx + stateParamx + endingParamx;
//跳转到微信网页授权页
window.location.href = lastUrlx;

3.前端发起或后端都可以发起,这里就说前端发起了,state参数是当前页面地址,如果页面地址长度太长可以不要携带参数,state的参数主要的后台处理完成后需要重定向的地址。

4.当这些都处理完成后,微信会调用第二步蚕参数指定的redirect_uri接口(之前我们配置的微信授权地址是前端地址,走了弯路),会携带之前的id=123参数,state参数,还有主要的code参数。

/**
* 微信新授权回调地址
* @param req
* @param rsp
* @param code
* @param sourceType
* @param state
* @return
* @throws Exception
* @return Object
* @author tyg
* @date 2019年4月1日下午2:33:35
*/
@RequestMapping(value = "/api/wechat/authBack")
public void authBack(HttpServletRequest req, HttpServletResponse rsp, Long id, Long shareId, Integer sourceType, String code, String state) throws Exception {
Assert.isBlank(code, "code can't be null!");
Assert.isBlank(state, "url can't be null!");
// 获取用户openid和unionid,没有头像、昵称
JSONObject info = wechatService.getUserOpenId(code);
// 登录,如果不存在则返回为null,再获取用户的头像和昵称信息
UserQuery userInfo = userI.weCharLogin(new WeChatUser(shareId, sourceType, info.getString("openid"), info.getString("unionid")));
if(userInfo == null) {
// 获取微信用户信息,有头像、昵称
info = wechatService.getUserInfoByOpenId(info.getString("access_token"), info.getString("openid"));
// 登录
userInfo = userI.weCharLogin(new WeChatUser(shareId, sourceType, info.getString("openid"),
info.getString("unionid"), info.getString("nickname"), info.getString("headimgurl")));
Assert.isNull(userInfo, "user is null!");
}
String encode = URLEncoder.encode(JSON.toJSONString(userInfo), "UTF-8");
state = URLDecoder.decode(state, "UTF-8");
state += state.contains("?") ? "&" : "?";
state = String.format("%sid=%s&shareId=%s&userInfo=%s", state, id == null ? "" : id, shareId == null ? "" : shareId, encode);
rsp.sendRedirect(state);
} /**
* 获取用户的openid
* @param code
* @return
* @throws Exception
* @return JSONObject
* @author tyg
* @date 2019年4月12日上午10:31:46
*/
private JSONObject getUserOpenId(String code) throws Exception {
Map<String, String> params = new HashMap<String, String>();
params.put("grant_type", "authorization_code");//
params.put("appid", WeChatProperties.AppID);
params.put("secret", WeChatProperties.AppSecret);
params.put("code", code); String jstoken = HttpUtils.sendGet("https://api.weixin.qq.com/sns/oauth2/access_token", params); if (jstoken == null) {
LOG.error("jstoken is null");
return null;
}
JSONObject jsonResult = JSONObject.parseObject(jstoken);
if (null != jsonResult.get("errcode")) {
LOG.error("wechat web auth err:" + jsonResult.get("errcode") + ":" + jsonResult.get("errmsg"));
return null;
}
return jsonResult;
} /**
* 根据openid获取用户信息,有头像、昵称
* @param access_token
* @param openid
* @return
* @throws Exception
* @return JSONObject
* @author tyg
* @date 2019年4月9日上午10:00:56
*/
public JSONObject getUserInfoByOpenId(String access_token,String openid) throws Exception {
Map<String, String> params = new HashMap<String, String>();
params.put("access_token", access_token);
params.put("openid", openid);
params.put("lang", "zh_CN");
String userinfo = HttpUtils.sendGet("https://api.weixin.qq.com/sns/userinfo", params);
JSONObject userJson = JSONObject.parseObject(userinfo);
if (null != userJson.get("errcode")) {
LOG.error(userJson.get("errmsg") + " get wechat user error:");
}
return userJson;
}

5.第四步中第二段代码中的APPID和AppSecret要替换成自己公众号的APPID和AppSecret,之所以先获取微信用户的openid信息,查询用户是否存在系统中,不存在的就要调用微信获取用户信息的接口,存在就不在调用,这样可以减少大约300-450毫秒,这个是我在本地测试获得的时间。

6.第四步包含了获取用户信息,注册,登录一起完成了,之前我们都是分开的由前端分次调用,比较慢,用户体验也不好。最后重定向到之前获取微信用户code时指定的state界面,并携带好参数。

7.未绑定开发者的微信服务号是没有unionid的,所以需要注意一下。

8.有什么不对的地方或者还有更多优化方案,欢迎讨论!

java、JavaScript获取微信用户信息登录优化方案的更多相关文章

  1. SpringBoot中获取微信用户信息从未如此简单!

    前言 不知道你是否参加过拼多多上邀请微信好友砍价功能,这个功能实现首先需要考虑的就是获取微信用户的信息.获取用户信息就是获取公众号下微信用户的信息,今天我就来讲讲如何从公众号下获取微信用户信息. 需要 ...

  2. Magicodes.WeiChat——使用OAuth 2.0获取微信用户信息

    使用Magicodes.WeiChat,可以很方便的获取到微信用户的信息.在使用OAuth 2.0之前,你先需要做以下操作: 1)在开发者中心修改[网页授权获取用户基本信息],在弹出的界面输入自己的根 ...

  3. 小白学react之网页获取微信用户信息

    通过上一篇<小白学react之EJS模版实战>我们学习了怎样通过EJS模版生成我们高定制化的index.html文件. 本篇我们将会继续延续我们的alt-tutorial项目的实战计划.去 ...

  4. python flask获取微信用户信息报404,nginx问题

    在学习flask与微信公众号时问题,发现测试自动回复/wechat8008时正常,而测试获取微信用户信息/wechat8008/index时出现404.查询资料后收发是nginx配置问题. 在loca ...

  5. php获取微信用户信息(没测试过)

    <?php /** * 通过$appid.$appsecret获得基础支持的接口唯一凭证access_token,返回值为array类型 */ function get_access_token ...

  6. python flask获取微信用户信息流程

    需要了解的几个url 用户第一次访问时的url,包含以下几个参数 https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID& ...

  7. Java 微信登录授权后获取微信用户信息昵称乱码问题解决

    String getUserInfoUrl = "https://api.weixin.qq.com/sns/userinfo?access_token="+access_toke ...

  8. Java微信公众平台开发(十二)--微信用户信息的获取

    转自:http://www.cuiyongzhi.com/post/56.html 前面的文章有讲到微信的一系列开发文章,包括token获取.菜单创建等,在这一篇将讲述在微信公众平台开发中如何获取微信 ...

  9. Java微信公众平台开发(十)--微信用户信息的获取

    前面的文章有讲到微信的一系列开发文章,包括token获取.菜单创建等,在这一篇将讲述在微信公众平台开发中如何获取微信用户的信息,在上一篇我们有说道微信用户和微信公众账号之间的联系可以通过Openid关 ...

随机推荐

  1. MySQL数字类型学习笔记

    数字类型 最近在看<MySQL技术内幕:SQL编程>并做了笔记,所以本博客是一篇笔记类型博客,分享出来方便自己复习,也可以帮助他人 整型 类型 占用空间 最小值(SIGNED) 最大值(S ...

  2. 获取系统相关信息 (CPU使用率 内存使用率 系统磁盘大小)

    引言 在软件开个过程中,对于软件的稳定性和使用率也是我们需要关注的 .  使用sigar来监控,简单方便!  使用说明:下载sigar jar及配合sigar的dll文件来用,需要将dll文件放到JD ...

  3. 疑问:Spring 中构造器、init-method、@PostConstruct、afterPropertiesSet 孰先孰后,自动注入发生时间

    一.前言 spring的一大优点就是扩展性很强,比如,在spring bean 的生命周期中,给我们预留了很多参与bean 的生命周期的方法.大致梳理一下,有以下几种: 通过实现 Initializi ...

  4. [算法]LeetCode 120:三角形最小路径和

    题目描述: 给定一个三角形,找出自顶向下的最小路径和.每一步只能移动到下一行中相邻的结点上. 例如,给定三角形: [ [2], [3,4], [6,5,7], [4,1,8,3]]自顶向下的最小路径和 ...

  5. MySQL(11)---约束

    MySQL(11)---约束 含义: 一种限制,用于限制表中的数据,为了保证表中的数据的准确和可靠性. 先把Mysql几种约束列出来: 主键约束 外键约束 唯一性约束 非空约束 默认值约束 自增约束 ...

  6. wpf datetime format

    <Style TargetType="{x:Type DatePickerTextBox}"> <Setter Property="Control.Te ...

  7. C# - 操作Word文档小实验

    前言 本篇主要记录:VS2019 WinFrm桌面应用程序实现对Word文档的简单操作. 准备工作 搭建WinFrm前台界面 添加必要的控件,如下图 NuGet包管理器 安装Microsoft.Off ...

  8. 关于EFCore线程内唯一

    EntityFramework的线程内唯一 EntityFramework的线程内唯一是通过httpcontext来实现的 public static DbContext DbContext() { ...

  9. mysql - 锁及事务的认识

    mysql事务特性:一致性原子性隔离性持久性 //mysql 事务隔离级别 读未提交 读未提交的数据 读已提交 读已提交的数据 串行序列化 一个事务完成了再执行另一个事务 可重复读(数据库默认) 就算 ...

  10. 数据库-表操作(CRUD)

    1.数据增删改 2.单表查询 3.正则表达式 4.多表查询 ​ 笛卡尔积 ​ 内连接 ​ 外链接 ​ 子查询 一.数据的增删改 为什么不说查 因为查询语句 有很多细节 所以先从简单的说起 添加数据: ...