微信授权登录:移动端[unionid](一)

专栏简介

💒个人主页

📄本栏目录

                          📖心灵鸡汤📖

生活中其实没有绝境,绝境在于你自己的心没有打开。

          ✍相关博文✍

微信分享开发:准备工作
微信PC端扫码登录


如果你有多端登录统一用户,或者是同一产品下不同子产品之间统一用户的需求的话,请提前在微信开放平台打通微信网页授权并绑定,不然的话后期打通用户处理起来比较麻烦。因为同一微信用户不同公众号生成的openid不一样,这样没办法统一用户,在微信开放平台绑定后,会有一个会有unionid,这个unionid是唯一的,这就可以统一用户,当然要花300RMB ,没有这种需求的话,可以不用管。

一,准备工作

①,微信公众平台申请配置,详情见微信分享开发:准备工作[微信公众平台以及微信中控服务配置](一)

②,微信公众平台已经给了详细的授权登录流程接口,我们只需要根据其提供的文档按照步骤实现即可,下面我将根据微信公众平台提供的文档结合项目进行实现。微信公众平台

二,开发实现预热

①,获取code

https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect

备注:redirect_uri需要进行urlEncode编码,scope使用的是snsapi_userinfo,下面提供一个范例

https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx010f4709f3abffe3&redirect_uri=http%3A%2F%2Fdevelope.sh01net.com%2Fauth%2FloginByWeixin&response_type=code&scope=snsapi_userinfo#wechat_redirect

唤起微信授权页面

确认登录后会换取到一个code值,并回调到redirect_uri配置的方法函数上并带着code值。

②,通过code换取access_token和openid,然后通过openid换取用户信息并保存。

③,简单的流程图

https://blog.csdn.net/qq_27185879/article/details/86598590

登录成功页面自由跳转实现方式:实现进入他人分享的指定页面:[带登录权限机制]

三,代码实现(精简了一下,仅供参考,不一定适用你的业务需求,但业务流程都一样的)

①,Controller层(微信回调地址)

    @RequestMapping(value = "/loginByWeixin",method = {RequestMethod.GET,RequestMethod.POST})public String LoginByWeixin(HttpServletResponse response, String code) throws IOException{System.out.print("======code======"+code);if(code==null || "".equals(code.trim())){response.sendRedirect("http://develope.sh01net.com/xc-ui-pc-static-portal/index.html#/login");//我这里跳转的是页面,也可以跳转相应方法return null;}try {String token;//weixin openIdString accessToken;//weixin accessTokenString unionid;String APPID="";//在微信公众平台申请的appidString APP_SECRET="";//在微信公众平台申请的APPSECRETWeixinOauth2Token weixinOauth2Token =AdvancedUtil.getOauth2AccessToken(APPID, APP_SECRET, code);// weixinOauth2Token 微信请求可能会报错。报错后为null,避免循环if(weixinOauth2Token==null || weixinOauth2Token.getOpenId()==null){response.sendRedirect("http://develope.sh01net.com/xc-ui-pc-static-portal/index.html#/login");return null;}token = weixinOauth2Token.getOpenId();accessToken = weixinOauth2Token.getAccessToken();//获取微信用户信息SNSUserInfo snsUserInfo =  AdvancedUtil.getSNSUserInfo(accessToken, token);//查询当前微信是否登录过,你可以根据openid查询或者Unionid查询,具体根据什么查询根据自己的实际情况unionid=snsUserInfo.getUnionid();XcUser xcUser =authService.getUserByUnionid(unionid);//替换成自己的查询方法String access_token=null;if(xcUser == null ){//存储用户信息到数据库。比较简单,具体代码省略...}response.sendRedirect("http://develope.sh01net.com/xc-ui-pc-static-portal/index.html#/search");//这里跳转授权登录成功的页面或方法return null;} catch (IOException e) {e.printStackTrace();logger.error(e);response.sendRedirect("http://develope.sh01net.com/xc-ui-pc-static-portal/index.html");return null;}}

②WeixinOauth2Token.java

/*** @author lvyq*网页授权信息*/
public class WeixinOauth2Token {/**网页授权接口调用凭证  */private String accessToken;/**凭证有效时长  */private int expiresIn;/**用于刷新凭证  */private String refreshToken;/**用户标识  */private String openId;/**用户授权作用域  */private String scope;/** * 返回 网页授权接口调用凭证*  * @return 网页授权接口调用凭证 */public String getAccessToken() {return accessToken;}/** * 设置 网页授权接口调用凭证*  * @param accessToken *            网页授权接口调用凭证 */public void setAccessToken(String accessToken) {this.accessToken = accessToken;}/** * 返回 凭证有效时长*  * @return 凭证有效时长 */public int getExpiresIn() {return expiresIn;}/** * 设置 凭证有效时长*  * @param expiresIn *            凭证有效时长 */public void setExpiresIn(int expiresIn) {this.expiresIn = expiresIn;}/** * 返回 用于刷新凭证*  * @return 用于刷新凭证 */public String getRefreshToken() {return refreshToken;}/** * 设置 用于刷新凭证*  * @param refreshToken *            用于刷新凭证 */public void setRefreshToken(String refreshToken) {this.refreshToken = refreshToken;}/** * 返回 用户标识*  * @return 用户标识 */public String getOpenId() {return openId;}/** * 设置 用户标识*  * @param openId *            用户标识 */public void setOpenId(String openId) {this.openId = openId;}/** * 返回 用户授权作用域*  * @return 用户授权作用域 */public String getScope() {return scope;}/** * 设置 用户授权作用域*  * @param scope *            用户授权作用域 */public void setScope(String scope) {this.scope = scope;}}

③,SNSUserInfo.java

/*** @author lvyq*  通过网页授权获取的用户信息*/
public class SNSUserInfo {/**用户标识  */private String openId;/**用户昵称  */private String nickname;/**性别(1是男性,2是女性,0是未知)  */private int sex;/**国家  */private String country;/**省份  */private String province;/**城市  */private String city;/**用户头像链接  */private String headImgUrl;/**用户特权信息  */private List<String> privilegeList;/**用户unionid,需要绑定开放平台才会获取到  */private String unionid;/** * 返回 用户标识*  * @return 用户标识 */public String getOpenId() {return openId;}/** * 设置 用户标识*  * @param openId *            用户标识 */public void setOpenId(String openId) {this.openId = openId;}/** * 返回 用户昵称*  * @return 用户昵称 */public String getNickname() {return nickname;}/** * 设置 用户昵称*  * @param nickname *            用户昵称 */public void setNickname(String nickname) {this.nickname = nickname;}/** * 返回 性别(1是男性,2是女性,0是未知)*  * @return 性别(1是男性,2是女性,0是未知) */public int getSex() {return sex;}/** * 设置 性别(1是男性,2是女性,0是未知)*  * @param sex *            性别(1是男性,2是女性,0是未知) */public void setSex(int sex) {this.sex = sex;}/** * 返回 国家*  * @return 国家 */public String getCountry() {return country;}/** * 设置 国家*  * @param country *            国家 */public void setCountry(String country) {this.country = country;}/** * 返回 省份*  * @return 省份 */public String getProvince() {return province;}/** * 设置 省份*  * @param province *            省份 */public void setProvince(String province) {this.province = province;}/** * 返回 城市*  * @return 城市 */public String getCity() {return city;}/** * 设置 城市*  * @param city *            城市 */public void setCity(String city) {this.city = city;}/** * 返回 用户头像链接*  * @return 用户头像链接 */public String getHeadImgUrl() {return headImgUrl;}/** * 设置 用户头像链接*  * @param headImgUrl *            用户头像链接 */public void setHeadImgUrl(String headImgUrl) {this.headImgUrl = headImgUrl;}/** * 返回 用户特权信息*  * @return 用户特权信息 */public List<String> getPrivilegeList() {return privilegeList;}/** * 设置 用户特权信息*  * @param privilegeList *            用户特权信息 */public void setPrivilegeList(List<String> privilegeList) {this.privilegeList = privilegeList;}/** * 返回 用户Unionid*  * @return 用户Unionid */public String getUnionid() {return unionid;}/** * 设置用户Unionid*  * @param 用户Unionid */public void setUnionid(String unionid) {this.unionid = unionid;}
}

④,AdvancedUtil .java 

/*** @author lvyq  获取网页授权凭证*/
public class AdvancedUtil {private static final Logger logger = LogManager.getLogger(AdvancedUtil.class);/*** 获取网页授权凭证* * @param appId*            公众账号的唯一标识* @param appSecret*            公众账号的密钥* @param code* @return WeixinAouth2Token*/public static WeixinOauth2Token getOauth2AccessToken(String appId,String appSecret, String code) {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", code);// 获取网页授权凭证JSONObject jsonObject = CommonUtil.httpsRequest(requestUrl, "GET", null);logger.info("// 获取网页授权凭证access_token"+jsonObject);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 (Exception e) {wat = null;int errorCode = jsonObject.getInt("errcode");String errorMsg = jsonObject.getString("errmsg");logger.info("获取网页授权凭证失败 errcode:{} errmsg:{}" + errorCode + errorMsg);e.printStackTrace();}}return wat;}/*** 通过网页授权获取用户信息* * @param accessToken* 网页授权接口调用凭证* @param openId*  用户标识* @return SNSUserInfo*/@SuppressWarnings({ "deprecation", "unchecked" })public static SNSUserInfo getSNSUserInfo(String accessToken, String openId) {SNSUserInfo snsUserInfo = null;// 拼接请求地址String requestUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openId=OPENID&lang=zh_CN";requestUrl = requestUrl.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openId);// 通过网页授权获取用户信息JSONObject jsonObject = CommonUtil.httpsRequest(requestUrl, "GET", null);logger.info("// 通过网页授权获取用户信息"+jsonObject);if (null != jsonObject) {try {snsUserInfo = new SNSUserInfo();// 用户的标识snsUserInfo.setOpenId(openId);// 昵称snsUserInfo.setNickname(jsonObject.getString("nickname"));// 性别(1是男性,2是女性,0是未知)snsUserInfo.setSex(jsonObject.getInt("sex"));// 用户所在国家snsUserInfo.setCountry(jsonObject.getString("country"));// 用户所在省份snsUserInfo.setProvince(jsonObject.getString("province"));// 用户所在城市snsUserInfo.setCity(jsonObject.getString("city"));// 用户头像snsUserInfo.setHeadImgUrl(jsonObject.getString("headimgurl"));// 用户特权信息snsUserInfo.setPrivilegeList(JSONArray.toList(jsonObject.getJSONArray("privilege"), List.class));//获取unionidsnsUserInfo.setUnionid(jsonObject.getString("unionid"));} catch (Exception e) {int errorCode = jsonObject.getInt("errcode");String errorMsg = jsonObject.getString("errmsg");logger.info("获取用户信息失败 errcode:{} errmsg:{}" + errorCode + errorMsg);e.printStackTrace();}}return snsUserInfo;}

⑤,CommonUtil.java

	/*** 发送https请求* * @param requestUrl*            请求地址* @param requestMethod*            请求方式(GET、POST)* @param outputStr*            提交的数据* @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)*//*** 发送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) {ce.printStackTrace();} catch (Exception e) {e.printStackTrace();}return jsonObject;}

⑥MyX509TrustManager.java(发送https请求绕过认证,注意引入的包)

import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.X509TrustManager;/*** @author lvyq 证书信任管理器*/
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;}
}

⑦,至此,已经实现了微信授权登录的业务。

微信授权登录:PC端扫码登录[unionid](二)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/31929.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第三方对接-微信登陆对接

对接第三方之微信登陆 由于目前市面上社交软件的使用排行来看&#xff0c;基本上微信一马当先。因此在大多数应用上都会内置微信登陆的场景&#xff0c;这时候我们就非常有必要熟悉微信的登录流程。 微信登陆 微信官方开发文档说明目前移动应用上微信登录仅支持原生登陆方式…

对三大数学软件 Mathematica 、Maple 、MATLAB 的小测试比较

今天一时兴起&#xff0c;突然想试试几个数学软件的功能&#xff0c;就测试了一个不定积分&#xff0c;看看哪个算得最好&#xff0c;最简洁。 计算&#xff1a; 以下计算结果我都一一验算了。 1).先在Mathematica&#xff08;我用的是在线的wolframalpha&#xff09;中计算,结…

【计算机图形学(译)】 二、各种各样的数学

【计算机图形学(译&#xff09;】 二、各种各样的数学 2 各种各样的数学 Miscellaneous Math2.1 集合和映射 Sets and Mapping2.1.1 反向映射 Inverse Mappings2.1.2 区间 Intervalsoft2.1.3 对数 Logarithms 2.2 解二次方程 Solving Quadratic Equations2.3 三角学 Trigonomet…

和托托一起学计算机图形学(一)-初识计算机图形学

文章目录 初识计算机图形学一、计算机科学与视觉信息处理二、计算机图形学的应用三、总结 数字图像基础一、像素二、RGB和CMY颜色模型三、颜色编码四、查色表五、图像文件六、总结 初识计算机图形学 一、计算机科学与视觉信息处理 计算机图形学&#xff1a;建模&#xff08;建…

如何使用 ChatGPT 掌握讲故事的艺术

想出一个故事情节&#xff0c;虽然有时很有趣&#xff0c;但可能是一个耗时的过程。或者你可能会发现自己遇到了作家的障碍——每个作家存在的祸根。 这个重要的灵感火花是 ChatGPT 可以提供帮助的地方。OpenAI流行的文本生成聊天机器人可以协助写作过程的任何部分&#xff0c…

仅剩1位73岁开发者苦撑!能求解超复杂物理方程式的计算程序,要没人维护了...

明敏 Alex 发自 凹非寺量子位 | 公众号 QbitAI 高能物理先进计算必备程序之一&#xff0c;快要没人维护了。 随着唯一的长期维护者达到73岁高龄&#xff0c;计算系统FORM的命运开始变得扑朔迷离起来。 过去30多年&#xff0c;这个程序被视为粒子物理学研究的基础工具之一&#…

苹果的头显,只要看一眼就行

阅读本文大概需要 1.66 分钟。 今年的 WWDC23 开发者大会&#xff0c;不少人表示 iOS 更新了个寂寞&#xff0c;但 Vision Pro 头显却意外吸引眼球&#xff0c;看来苹果工程师都忙着搞头显去了。 苹果的头显终于还是来了&#xff0c;关于它的传闻&#xff0c;似乎这几年从未间断…

AN OVERVIEW OF LANGUAGE MODELS RECENT DEVELOPMENTS AND OUTLOOK

LLM系列相关文章&#xff0c;针对《AN OVERVIEW OF LANGUAGE MODELS: RECENT DEVELOPMENTS AND OUTLOOK》的翻译。 语言模型综述&#xff1a;近年来的发展与展望 摘要1 引言2 语言模型的类型2.1 结构化LM2.2 双向LM2.3 置换LM 3 语言单元3.1 字符3.2 单词和子单词3.2.1 基于统…

使用 Sealos 三分钟打造鉴黄神器,我有个大胆的想法……

"NSFW" 是 "Not Safe For Work" 的缩写&#xff0c;通常用于标记那些在工作场所可能不适当的的在线内容。这种内容可能包含暴力、色情、血腥、或者其他可能被认为是令人反感或冒犯的材料&#xff0c;最常见的原因……是 18 成人内容。在许多在线平台&#…

8年前端带你HTML+CSS入门到实战(附视频+源码)

本文主要是解决&#xff1a; ☆ 想要自学前端开发&#xff0c; ☆ 但又不太想看博客文章&#xff0c; ☆ 觉得自学有点吃力&#xff0c;有点不知道学习步骤的同学 目录 一、HTML 1、需要了解熟练的标签 2、不太常用的标签 3、怎么算是HTML学好了&#xff0c;可以继续学CSS了…

NLP中的词向量对比:word2vec/glove/fastText/elmo/GPT/bert

点击上方&#xff0c;选择星标或置顶&#xff0c;每天给你送干货&#xff01; 阅读大概需要15分钟 跟随小博主&#xff0c;每天进步一丢丢 作者&#xff1a;JayLou&#xff0c;NLP算法工程师 知乎专栏&#xff1a;高能NLP之路 地址&#xff1a;https://zhuanlan.zhihu.com/p/56…

6款AI写作工具类网站推荐(第二版)

我们搜集了一些AI写作工具&#xff0c;希望对你有帮助&#xff0c;不论是在提升工作效率方面&#xff0c;还是在了解最新的AI技术方面&#xff0c;帮助你提升工作效率。 Notion AI https://www.notion.so/product/ai NotionAi可以提供AI智能写作&#xff0c;还能检查代码、语法…

国内大模型侵权第一案,6 年成果,被爬取 200+ 万次,仅索赔 1 元?

整理 | 郑丽媛 出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09; 上个月&#xff0c;学而思曾透露消息称&#xff0c;目前其正在自研数学大模型 MathGPT&#xff0c;即面向全球数学爱好者和科研机构&#xff0c;以数学领域的解题和讲题算法为核心打造而成。 彼时许多…

用GPT-4 写2022年天津高考作文能得多少分?

正文共 792 字&#xff0c;阅读大约需要 3 分钟 学生必备技巧&#xff0c;您将在3分钟后获得以下超能力&#xff1a; 积累作文素材 Beezy评级 &#xff1a;B级 *经过简单的寻找&#xff0c; 大部分人能立刻掌握。主要节省时间。 推荐人 | Kim 编辑者 | Linda ●图片由Lexica …

react聊天组件:用antd和react-chat-element组装的聊天列表

效果图&#xff1a; 安装库 用到了antd design和github上的一个库&#xff1a;react-chat-element &#xff08;1&#xff09;antd design&#xff1a; 安装&#xff1a;yarn add antd 修改 src/App.css&#xff0c;在文件顶部引入 antd/dist/antd.css import ~antd/dist/a…

chatgpt赋能python:人脸识别技术进程Python应用

人脸识别技术进程Python应用 人脸识别技术是计算机视觉领域的重要应用&#xff0c;随着深度学习技术的发展&#xff0c;越来越多的人开始关注并使用这种技术。Python作为一种高效、易用的编程语言&#xff0c;也在人脸识别领域得到了广泛应用&#xff0c;本文将介绍Python如何…

chatgpt赋能python:Python人脸搜索:进入智能搜索的新时代

Python人脸搜索&#xff1a;进入智能搜索的新时代 随着神经网络和深度学习的迅猛发展&#xff0c;人工智能已经成为许多领域中最重要的研究方向。人脸搜索的普及&#xff0c;是人工智能引领的技术革命最具有代表性的例子。Python作为一种高级编程语言&#xff0c;在人脸搜索领…

chatgpt赋能python:Python实现人脸识别系统

Python实现人脸识别系统 在当今科技发展的时代&#xff0c;人脸识别技术已经广泛应用于各行各业中&#xff0c;如安全防范、金融交易、医学检测等领域&#xff0c;成为了一个备受瞩目的技术。Python作为当今最流行的编程语言之一&#xff0c;其实现人脸识别系统的能力备受重视…

chatgpt赋能python:人脸识别软件的作用及发展

人脸识别软件的作用及发展 随着科技的飞速发展&#xff0c;人脸识别技术越来越广泛地应用于各个领域&#xff0c;例如安全监控、金融交易、社交网络等。人脸识别软件通过识别人脸图像中的特征来进行身份验证或辨认&#xff0c;具有高效、准确、便捷等优点。而Python作为一种易…

chatgpt赋能python:Python人脸匹配:自动识别人脸并进行匹配

Python人脸匹配&#xff1a;自动识别人脸并进行匹配 介绍 Python已经成为一种广泛使用的编程语言&#xff0c;在许多任务中被广泛应用。其中一项任务是人脸匹配&#xff0c;这是在安全性和身份验证方面非常有用的应用程序。Python提供了一些很好的库&#xff0c;使得在Python…