【2023最新】微信小程序中微信授权登录功能和退出登录功能实现讲解

本文主要是介绍【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最新】微信小程序中微信授权登录功能和退出登录功能实现讲解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/153522

相关文章

C++使用栈实现括号匹配的代码详解

《C++使用栈实现括号匹配的代码详解》在编程中,括号匹配是一个常见问题,尤其是在处理数学表达式、编译器解析等任务时,栈是一种非常适合处理此类问题的数据结构,能够精确地管理括号的匹配问题,本文将通过C+... 目录引言问题描述代码讲解代码解析栈的状态表示测试总结引言在编程中,括号匹配是一个常见问题,尤其是在

Java实现检查多个时间段是否有重合

《Java实现检查多个时间段是否有重合》这篇文章主要为大家详细介绍了如何使用Java实现检查多个时间段是否有重合,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录流程概述步骤详解China编程步骤1:定义时间段类步骤2:添加时间段步骤3:检查时间段是否有重合步骤4:输出结果示例代码结语作

Python使用国内镜像加速pip安装的方法讲解

《Python使用国内镜像加速pip安装的方法讲解》在Python开发中,pip是一个非常重要的工具,用于安装和管理Python的第三方库,然而,在国内使用pip安装依赖时,往往会因为网络问题而导致速... 目录一、pip 工具简介1. 什么是 pip?2. 什么是 -i 参数?二、国内镜像源的选择三、如何

使用C++实现链表元素的反转

《使用C++实现链表元素的反转》反转链表是链表操作中一个经典的问题,也是面试中常见的考题,本文将从思路到实现一步步地讲解如何实现链表的反转,帮助初学者理解这一操作,我们将使用C++代码演示具体实现,同... 目录问题定义思路分析代码实现带头节点的链表代码讲解其他实现方式时间和空间复杂度分析总结问题定义给定

Java覆盖第三方jar包中的某一个类的实现方法

《Java覆盖第三方jar包中的某一个类的实现方法》在我们日常的开发中,经常需要使用第三方的jar包,有时候我们会发现第三方的jar包中的某一个类有问题,或者我们需要定制化修改其中的逻辑,那么应该如何... 目录一、需求描述二、示例描述三、操作步骤四、验证结果五、实现原理一、需求描述需求描述如下:需要在

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

python使用fastapi实现多语言国际化的操作指南

《python使用fastapi实现多语言国际化的操作指南》本文介绍了使用Python和FastAPI实现多语言国际化的操作指南,包括多语言架构技术栈、翻译管理、前端本地化、语言切换机制以及常见陷阱和... 目录多语言国际化实现指南项目多语言架构技术栈目录结构翻译工作流1. 翻译数据存储2. 翻译生成脚本

如何通过Python实现一个消息队列

《如何通过Python实现一个消息队列》这篇文章主要为大家详细介绍了如何通过Python实现一个简单的消息队列,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录如何通过 python 实现消息队列如何把 http 请求放在队列中执行1. 使用 queue.Queue 和 reque

Python如何实现PDF隐私信息检测

《Python如何实现PDF隐私信息检测》随着越来越多的个人信息以电子形式存储和传输,确保这些信息的安全至关重要,本文将介绍如何使用Python检测PDF文件中的隐私信息,需要的可以参考下... 目录项目背景技术栈代码解析功能说明运行结php果在当今,数据隐私保护变得尤为重要。随着越来越多的个人信息以电子形

使用 sql-research-assistant进行 SQL 数据库研究的实战指南(代码实现演示)

《使用sql-research-assistant进行SQL数据库研究的实战指南(代码实现演示)》本文介绍了sql-research-assistant工具,该工具基于LangChain框架,集... 目录技术背景介绍核心原理解析代码实现演示安装和配置项目集成LangSmith 配置(可选)启动服务应用场景