【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, "退出登录成功!");}}

四、备注

大家要跟着我的教学视频去配套着看代码,了解整个登录流程的实现思路最重要! 以上是我列出的主要实现代码,页面实现那些根据自己需求去实现,我这就不贴了,如有其他遗漏代码,博客评论区可以提出,我会及时补充!

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

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

相关文章

电影产业的数据洞察:爬虫技术在票房分析中的应用

概述 电影产业是一个庞大而复杂的行业&#xff0c;涉及到各种各样的因素&#xff0c;如导演、演员、类型、主题、预算、宣传、口碑、评分、奖项等。这些因素都会影响电影的票房收入&#xff0c;也会反映出电影市场的动态和趋势。为了更好地了解电影产业的数据洞察&#xff0c;…

华为云云耀云服务器L实例评测|RabbitMQ的Docker版本安装 + 延迟插件安装 QQ邮箱和阿里云短信验证码的主题模式发送

前言 最近华为云云耀云服务器L实例上新&#xff0c;也搞了一台来玩&#xff0c;期间遇到各种问题&#xff0c;在解决问题的过程中学到不少和运维相关的知识。 本篇博客介绍RabbitMQ的Docker版本安装和配置&#xff0c;延迟插件的安装&#xff1b;结合QQ邮箱和阿里云短信验证码…

CMMI5认证哪些企业可以申请

CMMI5认证哪些企业可以申请 什么是CMMI5认证 CMMI&#xff08;Capability Maturity Model Integration&#xff09;是一种用于评估组织的软件工程能力的国际标准。CMMI模型包括5个等级&#xff0c;其中CMMI5是最高等级&#xff0c;代表组织具有达到持续优化和创新的能力。获得…

Elasticsearch:多语言语义搜索

在此示例中&#xff0c;我们将使用多语言嵌入模型 multilingual-e5-base 对混合语言文档的 toy 数据集执行搜索。 使用这个模型&#xff0c;我们可以通过两种方式进行搜索&#xff1a; 跨语言&#xff0c;例如使用德语查询来查找英语文档在非英语语言中&#xff0c;例如使用德…

深度学习在 NumPy、TensorFlow 和 PyTorch 中实现所有损失函数

目录 一、说明 二、内容提示 三、均方误差 (MSE) 损失 3.1 NumPy 中的实现 3.2 在 TensorFlow 中的实现 3.3 在 PyTorch 中的实现 四、二元交叉熵损失 4.1 NumPy 中的实现 4.2 在 TensorFlow 中的实现

【计算机网络】高级IO初步理解

文章目录 1. 什么是IO&#xff1f;什么是高效 IO? 2. IO的五种模型五种IO模型的概念理解同步IO与异步IO整体理解 3. 阻塞IO4. 非阻塞IOsetnonblock函数为什么非阻塞IO会读取错误&#xff1f;对错误码的进一步判断检测数据没有就绪时&#xff0c;返回做一些其他事情完整代码myt…

Android 13.0 SystemUI下拉状态栏时间格式的修改(一)

1.概述 在13.0产品定制化开发中,原生systemui的系统下拉状态栏时间格式为 某月某日周几 这样的格式 根据产品需要修改为年月日周几 某时某分这种格式 这就需要修改 显示时间的格式 在更新时间时 按照这个格式更新就可以了,接下来看如何实现这个功能 2.SystemUI下拉状态栏时…

Flutter笔记 - ListTile组件及其应用

Flutter笔记 ListTile组件及其应用 作者&#xff1a;李俊才 &#xff08;jcLee95&#xff09;&#xff1a;https://blog.csdn.net/qq_28550263 邮箱 &#xff1a;291148484163.com 本文地址&#xff1a;https://blog.csdn.net/qq_28550263/article/details/133411883 目 录 1. …

计算机毕设 大数据工作岗位数据分析与可视化 - python flask

文章目录 0 前言1 课题背景2 实现效果3 项目实现3.1 概括 3.2 Flask实现3.3 HTML页面交互及Jinja2 4 **完整代码**5 最后 0 前言 &#x1f525; 这两年开始毕业设计和毕业答辩的要求和难度不断提升&#xff0c;传统的毕设题目缺少创新和亮点&#xff0c;往往达不到毕业答辩的要…

STM32 大小端与字节对齐使用记录

大小端 串口数据包解析 MDK stm32 小段模式 接收到的数据包&#xff1a; DD 03 00 1B 11 59 00 00 00 00 17 70 00 00 2F 39 00 00 00 00 00 03 23 64 00 0E 02 0B 6E 0B 84 FC EA 77 其中数据内容为&#xff1a; DD 03 00 1B 11 59 //电压mV 00 00 00 00 17 70 …

R实现数据分布特征的视觉化——多笔数据之间的比较

大家好&#xff0c;我是带我去滑雪&#xff01; 如果要对两笔数据或者多笔数据的分布情况进行比较&#xff0c;Q-Q图、柱状图、星形图都是非常好的选择&#xff0c;下面开始实战。 &#xff08;1&#xff09;绘制Q-Q图 首先导入数据bankwage.csv文件&#xff0c;该数据集…

VSC-HVDC直流输电matlab仿真模型

微❤关注“电气仔推送”获得资料&#xff08;专享优惠&#xff09; VSC-HVDC直流输电仿真&#xff0c;换流站采用两电平结构&#xff0c;全控型器件&#xff08;IGBT&#xff09;&#xff0c;采用双环控制&#xff0c;包括电压外环&#xff0c;电流内环&#xff0c;分为d、q两…

使用关键字abstract 声明抽象类-PHP8知识详解

抽象类只能作为父类使用&#xff0c;因为抽象类不能被实例化。抽象类使用关键字abstract 声明&#xff0c;具体的使用语法格式如下&#xff1a; abstract class 抽象类名称{ //抽象类的成员变量列表 abstract function 成员方法1(参数); //抽象类的成员方法 abstract functi…

网络基础知识面试题1

VC++常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...)https://blog.csdn.net/chenlycly/article/details/124272585C++软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...)

GPU(国内外发展,概念参数(CUDA,Tensor Core等),类别,如何选型,NPU,TPU)

目录 前言 1.国内外GPU发展简述 2.GPU概念参数和选择标准 2.1 CUDA 2.2 Tensor Core 2.3 显存容量和显存位宽 2.4 精度 2.5 如何选择GPU 3.常见GPU类别和价格 3.1 GPU类别 3.2 GPU价格&#xff08;部分&#xff09; 3.3 GPU云服务器收费标准&#xff08;以阿里云为例&a…

五.docker+jenkins自动部署项目

一.敏捷开发相关概念 1.微服务的痛点 再来看一下我们的微服务架构 &#xff0c; 每个组件都需要服务器去部署&#xff0c;加起来可能需要几十个甚至上百个服务器。这样的微服务项目在部署上会遇到什么问题&#xff1f; 需要很多很多的服务器&#xff0c;服务器的采购安装&am…

代码随想录二刷day46

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、力扣139. 单词拆分二、力扣动态规划&#xff1a;关于多重背包&#xff0c;你该了解这些&#xff01; 前言 提示&#xff1a;以下是本篇文章正文内容&#x…

代码随想录二刷day48

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、力扣198. 打家劫舍二、力扣213. 打家劫舍 II三、力扣337. 打家劫舍 III 前言 一、力扣198. 打家劫舍 class Solution {public int rob(int[] nums) {if(nu…

Day-06 基于 Docker 安装 Nginx 镜像

1.去官方公有仓库查询nginx镜像 docker search nginx 2.拉取该镜像 docker pull nginx 3. 启动镜像&#xff0c;使用nginx服务&#xff0c;代理本机8080端口(测试是不是好使) docker run -d -p 8080:80 --name nginx-8080 nginx docker ps curl 127.0.0.1:8080

美格智能,从5G智能模组到车规级C-V2X|金球奖入围公示

2018年&#xff0c;高工智能汽车率先在中国智能汽车行业开创年度供应链评选活动&#xff08;高工金球奖年度评选&#xff09;&#xff0c;并致力于推动智能网联汽车产业的中国创新和本土化“竞合”。 2020年&#xff0c;高工智能汽车正式成立高工智能汽车研究院&#xff0c;通…