微信授权登陆

1.官方网站:微信登录功能 / 网页应用授权用户信息变更 (qq.com)

2.登陆流程:

和登陆微信没关系,是用户的微信号,和我程序的程序编号(微信给的 目前用的老师的),去请求微信的接口,微信给这个用户一个token,这个token在本系统中 只和该用户对应。登陆成功。

实际上有点出入,是用户扫码后确定登录后,自动去请求微信的接口,我拿不到用户的微信号。

3.具体实现

1》用户在页面点击登陆按钮,前端发送请求给后端

<li><a id="weixin" class="weixin" target="_blank" href="http://localhost:8160/eduuser/usercenter/wx/login"><i class="iconfont icon-weixin"/></a></li>

2》后端接收到请求,通过重定向去请求微信接口。返回重定向地址后,此时浏览器页面会自动新建一个页签,是微信的二维码登陆界面。

重定向到微信接口需要参数 appid这里使用谷粒学院老师的。

重定向地址是自己写的,在扫码之后微信会访问这个地址。

其他参数不清楚。

@GetMapping("login")public String genQrConnect(HttpSession session) {// 微信开放平台授权baseUrlString baseUrl = "https://open.weixin.qq.com/connect/qrconnect" +"?appid=%s" +"&redirect_uri=%s" +"&response_type=code" +"&scope=snsapi_login" +"&state=%s" +"#wechat_redirect";// 回调地址String redirectUrl = ConstantWxUtils.REDIRECT_URL; //获取业务服务器重定向地址try {redirectUrl = URLEncoder.encode(redirectUrl, "UTF-8"); //url编码} catch (UnsupportedEncodingException e) {throw new GuLiExeception(20001, e.getMessage());}// 防止csrf攻击(跨站请求伪造攻击)//String state = UUID.randomUUID().toString().replaceAll("-", "");//一般情况下会使用一个随机数String state = "imhelen";//为了让大家能够使用我搭建的外网的微信回调跳转服务器,这里填写你在ngrok的前置域名// 采用redis等进行缓存state 使用sessionId为key 30分钟后过期,可配置//键:"wechar-open-state-" + httpServletRequest.getSession().getId()//值:satte//过期时间:30分钟//生成qrcodeUrlString qrcodeUrl = String.format(baseUrl,ConstantWxUtils.APP_ID,redirectUrl,state);return "redirect:" + qrcodeUrl;}

3.用户在扫码登陆之后,微信会访问第二步携带的回调接口,并携带这个一个临时参数,在controller中获得此参数后,携带secret,访问正式的三方登陆接口,会返回access_token,这个access_token就是 该微信用户,在本系统中,唯一的token,token和用户是一对一的关系,微信登陆完成。

获得这个token后,可以再请求一次微信用户信息接口,获取用户的头像、微信名信息。

在获取完用户的头像、微信名信息后,重定向到前端地址,以重新加载刚才的扫码页面,并且在路径中携带token,前端发现路径中有token后,获取这个token,并携带这个token访问获取用户信息接口,获取用户信息。

    @GetMapping("callback")public String callBack(String code, String state) {//从redis中将state获取出来,和当前传入的state作比较//如果一致则放行,如果不一致则抛出异常:非法访问//向认证服务器发送请求换取access_tokenString baseAccessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token" +"?appid=%s" +"&secret=%s" +"&code=%s" +"&grant_type=authorization_code";String accessTokenUrl = String.format(baseAccessTokenUrl,ConstantWxUtils.APP_ID,ConstantWxUtils.APP_SECRECT,code);// 使用httpClient发送请求,得到返回结果JSONObject accesstokenInfo = HttpClientUtils.httpGet(accessTokenUrl);String access_token = (String) accesstokenInfo.get("access_token");String openid = (String) accesstokenInfo.get("openid");LambdaQueryWrapper<UcenterMember> lambdaQueryWrapper = new LambdaQueryWrapper();lambdaQueryWrapper.eq(UcenterMember::getOpenid, openid);UcenterMember checkUser = ucenterMemberService.getOne(lambdaQueryWrapper);if (checkUser == null) {//访问微信的资源服务器,获取用户信息String baseUserInfoUrl = "https://api.weixin.qq.com/sns/userinfo" +"?access_token=%s" +"&openid=%s";String userInfoUrl = String.format(baseUserInfoUrl, access_token, openid);try {JSONObject jsonObject = HttpClientUtils.httpGet(userInfoUrl);String nickName = jsonObject.getString("nickname");String headUrl = jsonObject.getString("headimgurl");UcenterMember ucenterMember = new UcenterMember(openid, nickName, headUrl);ucenterMemberService.save(ucenterMember);String jwtToken = JwtUtils.getJwtToken(ucenterMember.getId(), nickName);return "redirect:http://localhost:3000?guli_token=" + jwtToken;} catch (Exception e) {throw new GuLiExeception(20001, "用户未注册,获取腾讯用户信息失败");}}String jwtToken = JwtUtils.getJwtToken(checkUser.getId(), checkUser.getNickname());String temp=JwtUtils.getMemberIdByJwtTokenString(jwtToken);System.out.println("=======");System.out.println(temp);return "redirect:http://localhost:3000?guli_token="+jwtToken;}

前端代码, 前端发现路径中有token后,获取这个token,并携带这个token访问获取用户信息接口,获取用户信息。这是default.vue,当用户没有输入访问的具体地址时,默认访问此界面。

<template><div class="in-wrap"><!-- 公共头引入 --><header id="header"><section class="container"><h1 id="logo"><a href="#" title="谷粒学院"><img src="~/assets/img/logo.png" width="100%" alt="谷粒学院"></a></h1><div class="h-r-nsl"><ul class="nav"><router-link to="/" tag="li" active-class="current" exact><a>首页</a></router-link><router-link to="/course" tag="li" active-class="current"><a>课程</a></router-link><router-link to="/teacher" tag="li" active-class="current"><a>名师</a></router-link><router-link to="/article" tag="li" active-class="current"><a>文章</a></router-link><router-link to="/qa" tag="li" active-class="current"><a>问答</a></router-link></ul><ul class="h-r-login"><li v-if="!loginInfo.id" id="no-login"><a href="/login" title="登录"><em class="icon18 login-icon">&nbsp;</em><span class="vam ml5">登录</span></a>|<a href="/register" title="注册"><span class="vam ml5">注册</span></a></li><li v-if="loginInfo.id" id="is-login-one" class="mr10"><a id="headerMsgCountId" href="#" title="消息"><em class="icon18 news-icon">&nbsp;</em></a><q class="red-point" style="display: none">&nbsp;</q></li><li v-if="loginInfo.id" id="is-login-two" class="h-r-user"><a href="/ucenter" title><img:src="loginInfo.avatar"width="30"height="30"class="vam picImg"alt/><span id="userName" class="vam disIb">{{loginInfo.nickname}}</span></a><ahref="javascript:void(0);"title="退出"@click="logout()"class="ml5">退出</a></li><!-- /未登录显示第1 li;登录后显示第2,3 li --></ul><aside class="h-r-search"><form action="#" method="post"><label class="h-r-s-box"><inputtype="text"placeholder="输入你想学的课程"name="queryCourse.courseName"value/><button type="submit" class="s-btn"><em class="icon18">&nbsp;</em></button></label></form></aside></div><aside class="mw-nav-btn"><div class="mw-nav-icon"></div></aside><div class="clear"></div></section></header><!-- /公共头引入 --><nuxt /><!-- 公共底引入 --><footer id="footer"><section class="container"><div class><h4 class="hLh30"><span class="fsize18 f-fM c-999">友情链接</span></h4><ul class="of flink-list"><li><a href="http://www.atguigu.com/" title="尚硅谷" target="_blank">尚硅谷</a></li></ul><div class="clear"></div></div><div class="b-foot"><section class="fl col-7"><section class="mr20"><section class="b-f-link"><a href="#" title="关于我们" target="_blank">关于我们</a>|<a href="#" title="联系我们" target="_blank">联系我们</a>|<a href="#" title="帮助中心" target="_blank">帮助中心</a>|<a href="#" title="资源下载" target="_blank">资源下载</a>|<span>服务热线:010-56253825(北京) 0755-85293825(深圳)</span><span>Email:info@atguigu.com</span></section><section class="b-f-link mt10"><span>©2018课程版权均归谷粒学院所有 京ICP备17055252号</span></section></section></section><aside class="fl col-3 tac mt15"><section class="gf-tx"><span><img src="~/assets/img/wx-icon.png" alt /></span></section><section class="gf-tx"><span><img src="~/assets/img/wb-icon.png" alt /></span></section></aside><div class="clear"></div></div></section></footer><!-- /公共底引入 --></div>
</template>
<script>
import "~/assets/css/reset.css";
import "~/assets/css/theme.css";
import "~/assets/css/global.css";
import "~/assets/css/web.css";
import "~/assets/css/base.css";
import "~/assets/css/activity_tab.css";
import "~/assets/css/bottom_rec.css";
import "~/assets/css/nice_select.css";
import "~/assets/css/order.css";
import "~/assets/css/swiper-3.3.1.min.css";
import "~/assets/css/pages-weixinpay.css";
import cookie from "js-cookie";
import loginApi from "@/api/login";
export default {data() {return {guli_token: "",loginInfo: {id: "",age: "",avatar: "",mobile: "",nickname: "",sex: "",},};},created() {// 获取路径中的token中的值this.guli_token = this.$route.query.guli_token;if (this.guli_token) {cookie.set("guli_token", this.guli_token, { domain: "localhost" });console.log("执行微信登录");//如果可以取到token,用微信的方式登录this.wxLogin();}this.showInfo();},methods: {//创建方法,从cookie中获取用户信息showInfo() {var userStr = cookie.get("guli_ucenter");if (userStr) {//把字符串转换为JSON对象this.loginInfo = JSON.parse(userStr);}},//退出logout() {// domain 作用范围cookie.set("guli_ucenter", "", { domain: "localhost" });cookie.set("guli_token", "", { domain: "localhost" });console.log("回首页");//回到首页面window.location.href = "/";},//微信登陆wxLogin() {if (this.guli_token == "") return;//登录成功根据token获取用户信息loginApi.getLoginInfo().then((response) => {this.loginInfo = response.data.data.member;//将用户信息记录cookiecookie.set("guli_ucenter", JSON.stringify(this.loginInfo), {domain: "localhost",});});},},
};
</script>

 后端接收到前端发送的token,根据这个token查询用户信息并返回(用户信息在第三步上面已经获取到,并且保存数据库,这里只查就可以)

    @GetMapping("/info")public R geInfo(HttpServletRequest request) {String headers = "";Enumeration<String> names = request.getHeaderNames();while (names.hasMoreElements()) {String name = names.nextElement();String value = request.getHeader(name);headers += name + "=" + value + "\n";}System.out.println(headers + "请求用户信息请求头如上");String memberId = JwtUtils.getMemberIdByJwtToken(request);UcenterMember uCenterMember = ucenterMemberService.getById(memberId);return R.ok().data("member", uCenterMember);}

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

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

相关文章

WPF多值转换器

背景&#xff1a;实现Slider拖动可以调整rgb 单转换器&#xff1a;WPF中数据绑定转换器Converter-CSDN博客 在View中&#xff1a; <StackPanel Orientation"Vertical"><Slider x:Name"slider_R" Minimum"0" Maximum"255" Wi…

Python教程:拆分多级目录的方法

前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 如果有什么疑惑/资料需要的可以点击文章末尾名片领取源码 实现多级目录差分&#xff0c;举例说明如下&#xff1a; 假设现有的目录结构如下&#xff1a;1、2、2.1、2.2、2.3、2.4、3、4、5、6、6.1、6.1.1、6.1.2、6.1.3、6…

antv/g6绘制数据流向图

antv/g6绘制数据流向图 前言接口模拟数据htmlts页面效果 前言 在业务开发中需要绘制数据流向图&#xff0c;由于echarts关系图的限制以及需求的特殊要求&#xff0c;转而使用antv/g6实现&#xff0c;本文以代码的方式实现数据流向需求以及节点分组,版本"antv/g6": “…

Javadoc的讲解使用

概述&#xff1a;JavaDoc 是用于生成 Java 代码文档的工具。通过编写 JavaDoc 注释&#xff0c;可以为代码中的类、接口、方法、字段等元素添加文档注释&#xff0c;这些注释将被 JavaDoc 工具解析并生成相应的 HTML 文档。 目录 讲解 使用 结果 讲解 下面是一些关于 Java…

MCU常用外设总线

目录 前言一、时钟与中断二、GPIO三、ADC四、定时器4.1 基本定时器4.2 通用定时器4.2.1 输入捕获4.2.2 输出比较 五、UART5.1 通讯的基本概念5.1.1 串行通讯与并行通讯5.1.2 全双工、半双工及单工通讯5.1.3 同步通讯与异步通讯5.1.4 通信速率 5.2 异步串口UART5.2.1 物理层5.2.…

如何使用iPhone或iPad上的二维码共享Wi-Fi密码?这里有详细步骤

你有没有想过在不泄露网络密码的情况下与客人共享你的家庭或工作Wi-Fi?你肯定不是第一个这样想的人,我们很高兴地通知你,多亏了以下这个的变通方法,你现在可以使用iPhone或iPad做到这一点。 通常,如果你想让其他人访问网络,你需要共享你的Wi-Fi密码。苹果通过引入与任何…

嵌入式-stm32-江科大-EXTI外部中断

文章目录 一&#xff1a;EXTI外部中断&#xff08;external interrupt&#xff09;1.1 STM32 中断系统1.2 STM32外部中断EXTI1.3 实验&#xff1a;对射式红外传感器计次1.31 编程感想 1.4 实验&#xff1a;旋转编码器计次1.41 编程感想 道友&#xff1a;没有永久的巅峰也没有永…

Influxdb系列(一)influxdb2.7.x的部署安装

一、influxdb的介绍 InfluxDB 是一种时序数据库&#xff0c;时序数据库通常被用在监控场景&#xff0c;比如运维和 IOT&#xff08;物联网&#xff09;领域。这类数据库旨在存储时序数据并实时处理它们。 比如。我们可以写一个程序将服务器上 CPU 的使用情况每隔 10 秒钟向 In…

JVM-初始JVM

什么是JVM JVM 全称是 Java Virtual Machine&#xff0c;中文译名 Java虚拟机。JVM 本质上是一个运行在计算机上的程序&#xff0c;他的职责是运行Java字节码文件。 Java源代码执行流程如下&#xff1a; JVM的功能 1 - 解释和运行 2 - 内存管理 3 - 即时编译 解释和运行 解释…

2024转行程序员的请注意:均月薪在40-70k

前言 2023年&#xff0c;对大多数行业来说都是不太好过的一年。 对程序员来说也是如此&#xff0c;很多粉丝朋友都在说android工作特别难找&#xff0c;一个岗位都是几千份简历…大家心里都是特别的焦虑&#xff0c;本以为2024年就业情况会有好转&#xff0c;但实际上并非如此…

《WebKit 技术内幕》学习之十三(1):移动WebKit

1 触控和手势事件 1.1 HTML5规范 随着电容屏幕的流行&#xff0c;触控操作变得前所未有的流行起来。时至今日&#xff0c;带有多点触控功能已经成为了移动设备的标准配置&#xff0c;基于触控的手势识别技术也获得巨大的发展&#xff0c;如使用两个手指来缩放应用的大小等。…

基于SSM的蛋糕甜品店管理系统(有报告)。Javaee项目。ssm项目。

演示视频&#xff1a; 基于SSM的蛋糕甜品店管理系统&#xff08;有报告&#xff09;。Javaee项目。ssm项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;通过Spring…

C++ 数论相关题目(欧拉函数、筛法求欧拉函数)

1、欧拉函数 给定 n 个正整数 ai &#xff0c;请你求出每个数的欧拉函数。 欧拉函数的定义 1∼N 中与 N 互质的数的个数被称为欧拉函数&#xff0c;记为 ϕ(N) 。 若在算数基本定理中&#xff0c;Npa11pa22…pamm &#xff0c;则&#xff1a; ϕ(N) Np1−1p1p2−1p2…pm−1p…

SpringBoot项目多数据源配置与MyBatis拦截器生效问题解析

在日常项目开发中&#xff0c;由于某些原因&#xff0c;一个服务的数据源可能来自不同的库&#xff0c;比如&#xff1a; 对接提供的中间库&#xff0c;需要查询需要的数据同步数据&#xff0c;需要将一个库的数据同步到另一个库&#xff0c;做为同步工具的服务对接第三方系统…

肺癌相关文献6

第十四篇 Classification of lung adenocarcinoma based on stemness scores in bulk and single cell transcriptomes IF&#xff1a;6.0 中科院分区:2区 生物学WOS分区&#xff1a;Q1被引次数&#xff1a; 4 背景&#xff1a;癌细胞具有无限期自我更新和增殖的能力[2]。在一…

JavaScript进阶:WebAPIs重点知识整理1

目录 1 DOM修改元素内容 2 DOM修改元素常见属性 3 修改元素样式属性 3.1 通过style修改元素样式 3.2 通过类名className修改元素样式 3.3 通过classList修改元素样式 4 操作表单元素属性 5 自定义属性 6 定时器 7 事件监听 7.1 点击事件 click 7.2 鼠mouseenter和移…

Laya3.0 相机使用

摄像机&#xff0c;是3D场景里边最经常使用的对象了。 官方文档&#xff1a;点击这里学习 1.投影 Projection 透视&#xff1a; 模拟人眼的视觉效果&#xff0c;近大远小。模拟物理世界的规律&#xff0c;将眼睛或相机抽象成一个点&#xff0c;此时视锥体内的物体投影到视平…

YOLO 自己训练一个模型

一、准备数据集 我的版本是yolov8 8.11 这个目录结构很重要 ultralytics-main | datasets|coco|train|val 二、训练 编写yaml 文件 # Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..] path…

Java项目:基于SSM框架实现同城蔬菜配送管理系统(SSM+B/S架构+源码+数据库+毕业论文)

一、项目简介 本项目是一套ssm825基于SSM框架实现同城蔬菜配送管理系统&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Java学习者。 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&…

【Web前端开发基础】CSS3之空间转换和动画

CSS3之空间转换和动画 目录 CSS3之空间转换和动画一、空间转换1.1 概述1.2 3D转换常用的属性1.3 3D转换&#xff1a;translate3d&#xff08;位移&#xff09;1.4 3D转换&#xff1a;perspective&#xff08;视角&#xff09;1.5 3D转换&#xff1a;rotate3d&#xff08;旋转&a…