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