【2023最新】微信小程序中微信授权登录功能和退出登录功能实现讲解
文章目录
- 一、讲解视频
- 二、小程序前端代码
- 三、后端Java代码
- 四、备注
一、讲解视频
教学视频地址: 视频地址
二、小程序前端代码
// pages/profile/profile.js
import api from "../../utils/api";
import { myRequest } from "../../utils/request";
import Notify from "@vant/weapp/notify/notify";
import Cache from "../../utils/cache";
import Tool from "../../utils/tool";Page({/*** 页面的初始数据*/data: {isLogin: false,userInfo: {username: "还未登录,请先登录!",headPic: api.BASE_URL + "/photo/view?filename=common/mine_normal.jpg"},basePhotoUrl: api.BASE_URL + "/photo/view?filename=",editUser: {},profileDialogVisible: false},/*** 生命周期函数--监听页面加载*/onLoad: function (options) {this.validateLoginState();},/*** 生命周期函数--监听页面初次渲染完成*/onReady: function () {},/*** 生命周期函数--监听页面显示*/onShow: function () {},/*** 生命周期函数--监听页面隐藏*/onHide: function () {},/*** 生命周期函数--监听页面卸载*/onUnload: function () {},/*** 页面相关事件处理函数--监听用户下拉动作*/onPullDownRefresh: function () {this.validateLoginState();},/*** 页面上拉触底事件的处理函数*/onReachBottom: function () {},/*** 用户点击右上角分享*/onShareAppMessage: function () {},// 预览图片previewHead: function () {let userInfo = this.data.userInfo;let basePhotoUrl = this.data.basePhotoUrl;wx.previewImage({current: userInfo.headPic === userInfo.wxHeadPic ? userInfo.wxHeadPic : basePhotoUrl + userInfo.headPic,urls: [userInfo.headPic === userInfo.wxHeadPic ? userInfo.wxHeadPic : basePhotoUrl + userInfo.headPic]})},// 验证登录状态validateLoginState: async function() {wx.showLoading({title: "获取登录信息...",mask: true})const loginUser = Cache.getCache(getApp().globalData.SESSION_KEY_LOGIN_USER);if(Tool.isEmpty(loginUser)) {wx.hideLoading();return;}const res = await myRequest({url: api.BASE_URL + "/app/user/get_login_user",method: "POST",data: {token: loginUser}});if(res.data.code === 0) {this.setData({userInfo: res.data.data,isLogin: true,editUser: res.data.data})}wx.hideLoading();wx.stopPullDownRefresh();},// 登录操作getLoginUser: function() {wx.showLoading({title: "正在登录...",mask: true})wx.getUserProfile({desc: "获取用户相关信息",success: res => {if(res.errMsg === "getUserProfile:ok") {let username = res.userInfo.nickName;let headPic = res.userInfo.avatarUrl;wx.login({success: async res => {if (res.errMsg === "login:ok") {// 调用后端接口,验证用户数据const response = await myRequest({url: api.BASE_URL + "/app/user/wx_login",method: "POST",data: {wxHeadPic: headPic,wxUsername: username,code: res.code}});if(response.data.code === 0) {Notify({ type: "success", message: response.data.msg, duration: 1000 });Cache.setCache(getApp().globalData.SESSION_KEY_LOGIN_USER, response.data.data.token, 3600);this.setData({userInfo: response.data.data,editUser: response.data.data,isLogin: true});} else {Notify({ type: "danger", message: response.data.msg, duration: 2000 });}} else {wx.showToast({icon: "error",title: "登录失败"});}wx.hideLoading();},fail: res => {wx.showToast({icon: "error",title: "登录失败"});wx.hideLoading();}})} else {wx.showToast({icon: "error",title: "获取用户失败"});wx.hideLoading();}},fail: res => {wx.showToast({icon: "error",title: "获取用户失败"});wx.hideLoading();}})}, // 登录验证authUser: function() {const loginUser = Cache.getCache(getApp().globalData.SESSION_KEY_LOGIN_USER);if(Tool.isEmpty(loginUser)) {Notify({ type: "danger", message: "请先登录!", duration: 2000 });return true;} else {return false;}},// 退出登录logout: async function() {const loginUser = Cache.getCache(getApp().globalData.SESSION_KEY_LOGIN_USER);const res = await myRequest({url: api.BASE_URL + "/app/user/logout",method: "POST",data: {token: loginUser}});if(res.data.code === 0) {Notify({ type: "success", message: res.data.msg, duration: 1000 });}Cache.removeCache(getApp().globalData.SESSION_KEY_LOGIN_USER); this.setData({isLogin: false, userInfo: {username: "还未登录,请先登录!",headPic: api.BASE_URL + "/photo/view?filename=common/mine_normal.jpg"}});},})
三、后端Java代码
<!--引入http连接依赖-->
<dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.3</version>
</dependency>
package com.yjq.programmer.service.impl;import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.yjq.programmer.bean.CodeMsg;
import com.yjq.programmer.dao.UserMapper;
import com.yjq.programmer.domain.User;
import com.yjq.programmer.domain.UserExample;
import com.yjq.programmer.dto.LoginDTO;
import com.yjq.programmer.dto.PageDTO;
import com.yjq.programmer.dto.ResponseDTO;
import com.yjq.programmer.dto.UserDTO;
import com.yjq.programmer.enums.RoleEnum;
import com.yjq.programmer.service.IUserService;
import com.yjq.programmer.utils.CommonUtil;
import com.yjq.programmer.utils.CopyUtil;
import com.yjq.programmer.utils.UuidUtil;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.TimeUnit;/*** @author 杨杨吖* @QQ 823208782* @WX yjqi12345678* @create 2023-09-25 17:08*/
@Service
@Transactional
public class UserServiceImpl implements IUserService {@Resourceprivate UserMapper userMapper;@Resourceprivate StringRedisTemplate stringRedisTemplate;private static final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);// 填写上你的AppID,如何获取AppID自行百度,这步骤很简单private final static String APP_ID = "wxc41c88e07f3f1bd7";// 填写上你的AppSecret,如何获取AppSecret自行百度,这步骤很简单private final static String APP_SECRET = "99a06dc0d1e21d797a9915baca08c872";// 微信小程序登录校验请求地址private final static String LOGIN_URL = "https://api.weixin.qq.com/sns/jscode2session";/*** 小程序授权登录验证* @param userDTO* @return*/@Overridepublic ResponseDTO<UserDTO> appWxLogin(UserDTO userDTO) {String url = LOGIN_URL + "?appid=" + APP_ID + "&secret="+ APP_SECRET + "&grant_type=authorization_code&js_code=" + userDTO.getCode();HttpClient client = HttpClients.createDefault(); // 创建默认http连接HttpGet getRequest = new HttpGet(url);// 创建一个post请求LoginDTO loginDTO = new LoginDTO();try {// 用http连接去执行get请求并且获得http响应HttpResponse response = client.execute(getRequest);// 从response中取到响实体HttpEntity entity = response.getEntity();// 把响应实体转成文本String html = EntityUtils.toString(entity);loginDTO = JSON.parseObject(html, LoginDTO.class);if(null == loginDTO.getErrcode()) {userDTO.setWxId(loginDTO.getOpenid());} else {return ResponseDTO.errorByMsg(CodeMsg.USER_WX_LOGIN_ERROR);}} catch (Exception e) {e.printStackTrace();return ResponseDTO.errorByMsg(CodeMsg.USER_WX_LOGIN_ERROR);}// 使用微信openId查询是否有此用户UserExample userExample = new UserExample();userExample.createCriteria().andWxIdEqualTo(userDTO.getWxId());List<User> userList = userMapper.selectByExample(userExample);if(null != userList && userList.size() > 0) {// 已经存在用户信息,读取数据库中用户信息User user = userList.get(0);userDTO = CopyUtil.copy(user, UserDTO.class);} else {// 数据库中不存在,注册用户信息User user = CopyUtil.copy(userDTO, User.class);// 自定义工具类,生成8位uuiduser.setId(UuidUtil.getShortUuid());user.setUsername(user.getWxUsername());user.setHeadPic(user.getWxHeadPic());user.setRoleId(RoleEnum.USER.getCode());if(userMapper.insertSelective(user) == 0) {return ResponseDTO.errorByMsg(CodeMsg.USER_REGISTER_ERROR);}// domain转dto 这步不是必须的,我项目中需要这步userDTO = CopyUtil.copy(user, UserDTO.class);}userDTO.setToken(UuidUtil.getShortUuid());stringRedisTemplate.opsForValue().set("USER_" + userDTO.getToken(), JSON.toJSONString(userMapper.selectByPrimaryKey(userDTO.getId())), 3600, TimeUnit.SECONDS);return ResponseDTO.successByMsg(userDTO, "登录成功!");}/*** 获取当前登录用户* @param token* @return*/@Overridepublic ResponseDTO<UserDTO> getLoginUser(String token) {if(CommonUtil.isEmpty(token)){return ResponseDTO.errorByMsg(CodeMsg.USER_SESSION_EXPIRED);}String value = stringRedisTemplate.opsForValue().get("USER_" + token);if(CommonUtil.isEmpty(value)){return ResponseDTO.errorByMsg(CodeMsg.USER_SESSION_EXPIRED);}UserDTO selectedUserDTO = JSON.parseObject(value, UserDTO.class);return ResponseDTO.success(CopyUtil.copy(userMapper.selectByPrimaryKey(selectedUserDTO.getId()), UserDTO.class));}/*** 退出登录操作* @param userDTO* @return*/@Overridepublic ResponseDTO<Boolean> logout(UserDTO userDTO) {if(!CommonUtil.isEmpty(userDTO.getToken())){// token不为空 清除redis中数据stringRedisTemplate.delete("USER_" + userDTO.getToken());}return ResponseDTO.successByMsg(true, "退出登录成功!");}}
四、备注
大家要跟着我的教学视频去配套着看代码,了解整个登录流程的实现思路最重要! 以上是我列出的主要实现代码,页面实现那些根据自己需求去实现,我这就不贴了,如有其他遗漏代码,博客评论区可以提出,我会及时补充!
相关文章:
【2023最新】微信小程序中微信授权登录功能和退出登录功能实现讲解
文章目录 一、讲解视频二、小程序前端代码三、后端Java代码四、备注 一、讲解视频 教学视频地址: 视频地址 二、小程序前端代码 // pages/profile/profile.js import api from "../../utils/api"; import { myRequest } from "../../utils/reques…...
复习 --- C++运算符重载
.5 运算符重载 运算符重载概念:对已有的运算符重新进行定义,赋予其另外一种功能,以适应不同的数据类型 4.5.1 加号运算符重载 作用:实现两个自定义数据类型相加的运算 1 #include<iostream>2 using namespace std;3 /…...
复习 --- select并发服务器
selectIO多路复用并发服务器,是通过轮询检测文件描述符来实现并发 将内核要检测文件描述符放入集合中,调用select函数,通知内核区检测文件描述符集合中的文件描述符是否准备就绪,即对应的空间中是否有数据 对准备就绪的文件描述…...

程序三高的方法
程序三高的方法 目录概述需求: 设计思路实现思路分析1.1)高并发 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy,skip hardness,make a better result,wait for change,c…...

全志ARM926 Melis2.0系统的开发指引⑦
全志ARM926 Melis2.0系统的开发指引⑦ 编写目的11. 调屏11.1. 调屏步骤简介11.1.1. 判断屏接口。11.1.2. 确定硬件连接。11.1.3. 配置显示部分 sys_config.fex11.1.3.1. 配置屏相关 IO 11.1.4. Lcd_panel_cfg.c 初始化文件中配置屏参数11.1.4.1. LCD_cfg_panel_info11.1.4.2. L…...

全志ARM926 Melis2.0系统的开发指引⑧
全志ARM926 Melis2.0系统的开发指引⑧ 编写目的12.5. 应用程序编写12.5.1. 简单应用编写12.5.1.1. 注册应用12.5.1.2. 创建管理窗口12.5.1.3. 实现管理窗口消息处理回调函数12.5.1.4. 创建图层12.5.1.5. 创建 framewin12.5.1.6. 实现 framewin 消息处理回调函数 -. 全志相关工具…...

区别对比表:阿里云轻量服务器和云服务器ECS对照表
阿里云轻量应用服务器和云服务器ECS区别对照表,一看就懂的适用人群、使用场景、优缺点、使用限制、计费方式、网路和镜像系统全方位对比,阿里云服务器网分享ECS和轻量应用服务器区别对照表: 目录 轻量应用服务器和云服务器ECS区别对照表 轻…...

【做题笔记】多项式/FFT/NTT
HDU1402 - A * B Problem Plus 题目链接 大数乘法是多项式的基础应用,其原理是将多项式 f ( x ) a 0 a 1 x a 2 x 2 a 3 x 3 ⋯ a n x n f(x)a_0a_1xa_2x^2a_3x^3\cdotsa_nx^n f(x)a0a1xa2x2a3x3⋯anxn中的 x 10 x10 x10,然后让大数的…...

网课搜题 小猿题库多接口微信小程序源码 自带流量主
多接口小猿题库等综合网课搜题微信小程序源码带流量主,网课搜题小程序, 可以开通流量主赚钱 搭建教程1, 微信公众平台注册自己的小程序2, 下载微信开发者工具和小程序的源码3, 上传代码到自己的小程序 源码下载:https://download.csdn.net/download/m0_…...
centos安装conda python3.10
最新版本的conda自带python3.10,直接安装即可。 手动创建一个conda文件夹,进入该文件夹,然后执行以下操作步骤。 1.下载 curl -O https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh2.安装 sh Miniconda3-latest-Linux-x86_64.…...

解密京东面试:如何应对Redis缓存穿透?
亲爱的小伙伴们,大家好!欢迎来到小米的微信公众号,今天我们要探讨一个在面试中可能会遇到的热门话题——Redis缓存穿透以及如何解决它。这个话题对于那些渴望进入技术领域的小伙伴们来说,可是必备的哦! 认识Redis缓存…...
#力扣:1. 两数之和@FDDLC
1. 两数之和 - 力扣(LeetCode) 一、Java import java.util.HashMap;class Solution {public int[] twoSum(int[] nums, int target) { //返回数组HashMap<Integer, Integer> map new HashMap<>(); //键:元素值;值&…...

【小沐学Python】各种Web服务器汇总(Python、Node.js、PHP、httpd、Nginx)
文章目录 1、Web服务器2、Python2.1 简介2.2 安装2.3 使用2.3.1 http.server(命令)2.3.2 socketserver2.3.3 flask2.3.4 fastapi 3、NodeJS3.1 简介3.2 安装3.3 使用3.3.1 http-server(命令)3.3.2 http3.3.3 express 4、PHP4.1 简…...

【AI视野·今日Robot 机器人论文速览 第四十六期】Tue, 3 Oct 2023
AI视野今日CS.Robotics 机器人学论文速览 Tue, 3 Oct 2023 Totally 76 papers 👉上期速览✈更多精彩请移步主页 Interesting: 📚Aerial Interaction with Tactile, 无人机与触觉的结合,实现空中交互与相互作用。(from CMU) website&#…...
macOS三种软件安装目录以及环境变量优先级
一、系统自带应用 这些软件(以git为例)位于根目录下的/usr/bin/xxx,又因为系统级环境变量文件/etc/paths已指定了命令查找位置: /usr/local/bin /System/Cryptexes/App/usr/bin /usr/bin /bin /usr/sbin /sbin所以这些自带应用可…...

嵌入式Linux裸机开发(一)基础介绍及汇编LED驱动
系列文章目录 文章目录 系列文章目录前言IMX6ULL介绍主要资料IO表现形式 汇编LED驱动原理图初始化流程时钟设置IO复用设置电气属性设置使用GPIO 编写驱动编译程序编译.o文件地址链接.elf格式转换.bin反汇编(其他) 综合成Makefile完成一步编译烧录程序imx…...

企业微信机器人对接GPT
现在网上大部分微信机器人项目都是基于个人微信实现的,常见的类库都是模拟网页版微信接口。 个人微信作为我们自己日常使用的工具,也用于支付场景,很怕因为违规而被封。这时,可以使用我们的企业微信机器人,利用企业微信…...

【数据结构】排序(1) ——插入排序 希尔排序
目录 一. 直接插入排序 基本思想 代码实现 时间和空间复杂度 稳定性 二. 希尔排序 基本思想 代码实现 时间和空间复杂度 稳定性 一. 直接插入排序 基本思想 把待排序的记录按其关键码值的大小依次插入到一个已经排好序的有序序列中,直到所有的记录插入完为止&…...

Python 列表推导式深入解析
Python 列表推导式深入解析 列表推导式是 Python 中的一种简洁、易读的方式,用于创建列表。它基于一个现有的迭代器(如列表、元组、集合等)来生成新的列表。 基本语法: 列表推导式的基本形式如下: [expression for…...
信息学奥赛一本通-编程启蒙3103:练18.3 组别判断
3103:练18.3 组别判断 时间限制: 1000 ms 内存限制: 65536 KB 提交数: 1963 通过数: 1418 【题目描述】 信息学课上要同学分组做期末报告,分组的方式为依座号顺序,每 3个人一组。如:1, 2, 3 为第一组,4, …...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...

ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...

html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...

云原生玩法三问:构建自定义开发环境
云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...

HarmonyOS运动开发:如何用mpchart绘制运动配速图表
##鸿蒙核心技术##运动开发##Sensor Service Kit(传感器服务)# 前言 在运动类应用中,运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据,如配速、距离、卡路里消耗等,用户可以更清晰…...

人机融合智能 | “人智交互”跨学科新领域
本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...
JS手写代码篇----使用Promise封装AJAX请求
15、使用Promise封装AJAX请求 promise就有reject和resolve了,就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...

Unity UGUI Button事件流程
场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...