一、讲解视频
教学视频地址: 视频地址文章来源:https://www.toymoban.com/news/detail-720783.html
二、小程序前端代码
// 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 {
@Resource
private UserMapper userMapper;
@Resource
private 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
*/
@Override
public 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);// 创建一个get请求
LoginDTO loginDTO = new LoginDTO(); // 存储下面http请求返回的结果
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()); // 拿到openId,存入userDTO实体
} 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位uuid
user.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);
}
// 生成8位uuid作为登录的token,标识用户的登录信息
userDTO.setToken(UuidUtil.getShortUuid());
// 把用户登录信息存入redis中,定时1小时
stringRedisTemplate.opsForValue().set("USER_" + userDTO.getToken(), JSON.toJSONString(userMapper.selectByPrimaryKey(userDTO.getId())), 3600, TimeUnit.SECONDS);
return ResponseDTO.successByMsg(userDTO, "登录成功!");
}
/**
* 获取当前登录用户
* @param token
* @return
*/
@Override
public 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
*/
@Override
public ResponseDTO<Boolean> logout(UserDTO userDTO) {
if(!CommonUtil.isEmpty(userDTO.getToken())){
// token不为空 清除redis中数据
stringRedisTemplate.delete("USER_" + userDTO.getToken());
}
return ResponseDTO.successByMsg(true, "退出登录成功!");
}
}
四、备注
大家要跟着我的教学视频去配套着看代码,了解整个登录流程的实现思路最重要! 以上是我列出的主要实现代码,页面样式那些根据自己需求去实现,我这就不贴了。文章来源地址https://www.toymoban.com/news/detail-720783.html
到了这里,关于【2023最新】微信小程序中微信授权登录功能和退出登录功能实现讲解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!