目录

小程序微信登录接口演示

导入项目

method1 

method2

 小程序授权登录

图解

 后端导入

 前端代码导入 

 案列演示

前端调用接口地址

个人中心

后端代码

WxAuthController

 效果展示

小程序微信登录接口演示

导入项目

 

然后在输入我们自己的微信小程序appid直接确认即可

method1 

method1获取用户的信息存在一定的风险,所以我们要把它的方法改成false

 效果展示

method2

method2方式获取用户信息须经用户本人确认才会获取相应信息,相对与来说method1方发更为安全

我们把下面的false改成true

效果展示

 

 小程序授权登录

微信小程序提供了授权登录功能,以便用户可以使用微信账号登录小程序并获取相关信息。在实现授权登录的过程中,可以通过调用微信小程序的API获取用户的基本信息和权限。

 小程序的步骤

在小程序的后台配置中,添加小程序的合法域名。这是为了保证小程序可以与微信服务器进行通信。使用wx.login接口获取用户的临时登录凭证(code)。向后端服务器发送code,并使用code和微信分配的AppID、AppSecret等参数通过wx.request发起请求到微信服务器。微信服务器返回给开发者一个session_key。后端服务器将session_key和用户的openid进行关联,并保存在数据库中,用于后续的身份认证。调用wx.getUserInfo接口获取用户信息,此接口需要用户授权,可以通过button组件的open-type="getUserInfo"属性触发授权弹窗。将获取到的用户信息返回给前端,前端进行相应的展示和使用。

值得注意的是,在开发过程中,需要进行相应的数据保护,避免用户敏感信息的泄露和滥用,提升用户的信息安全保障。同时,还需遵循微信官方的开发规范和最佳实践。

图解

 后端导入

 前端代码导入 

 案列演示

前端调用接口地址

api.js

// 以下是业务服务器API地址

// 本机开发API地址

var WxApiRoot = 'http://localhost:8080/oapro/wx/';

// 测试环境部署api地址

// var WxApiRoot = 'http://192.168.191.1:8080/oapro/wx/';

// 线上平台api地址

//var WxApiRoot = 'https://www.oa-mini.com/demo/wx/';

module.exports = {

IndexUrl: WxApiRoot + 'home/index', //首页数据接口

SwiperImgs: WxApiRoot+'swiperImgs',

MettingInfos: WxApiRoot+'meeting/list',

AuthLoginByWeixin: WxApiRoot + 'auth/login_by_weixin', //微信登录

UserIndex: WxApiRoot + 'user/index', //个人页面用户相关信息

AuthLogout: WxApiRoot + 'auth/logout', //账号登出

AuthBindPhone: WxApiRoot + 'auth/bindPhone' //绑定微信手机号

};

这里要注意的是 需要对应后台的请求地址之后进行数据的访问。

个人中心

index.wxml

我主持的会议

{{metting_pubs}}

我参与的会议

{{metting_joins}}

我发布的投票

1

我参与的投票

10

消息

设置

在index.js中编写数据请求方法

// pages/ucenter/index/index.js

var util = require('../../../utils/util.js');

var api = require('../../../config/api.js');

const app = getApp();

Page({

/**

* 页面的初始数据

*/

data: {

userInfo: {

nickName: '点击登录',

avatarUrl: '/static/images/avatar.png'

},

hasLogin: false,

metting_pubs: '',

metting_joins: ''

},

/**

* 生命周期函数--监听页面加载

*/

onLoad(options) {

},

/**

* 生命周期函数--监听页面显示

*/

onShow() {

this.getUserInfo();

},

getUserInfo() {

// console.log('ucenter.index.app.globalData.hasLogin='+app.globalData.hasLogin)

//获取用户的登录信息

if (app.globalData.hasLogin) {

let userInfo = wx.getStorageSync('userInfo');

this.setData({

userInfo: userInfo,

hasLogin: true

});

//查询个人统计信息

util.request(api.UserIndex).then(res => {

if (res.errno === 0) {

this.setData({

metting_pubs: res.data.metting_pubs,

metting_joins: res.data.metting_joins

});

}

});

}

},

goLogin() {

if (!this.data.hasLogin) {

wx.navigateTo({

url: "/pages/auth/login/login"

});

}

},

/**

* 页面跳转

*/

goPages: function (e) {

if (this.data.hasLogin) {

wx.navigateTo({

url: e.currentTarget.dataset.url

});

} else {

wx.navigateTo({

url: "/pages/auth/login/login"

});

};

}

})

接着我们创建一个用户登入后的设置页面为 : user

var util = require('../../../utils/util.js');

var api = require('../../../config/api.js');

var user = require('../../../utils/user.js');

var app = getApp();

Page({

/**

* 页面的初始数据

*/

data: {

userInfo: {},

hasLogin: false,

userSharedUrl: ''

},

/**

* 生命周期函数--监听页面加载

*/

onLoad: function (options) {

},

onShow: function () {

let that = this;

//获取用户的登录信息

let userInfo = wx.getStorageSync('userInfo');

this.setData({

userInfo: userInfo,

hasLogin: true

});

},

getPhoneNumber: function (e) {

let that = this;

if (e.detail.errMsg !== "getPhoneNumber:ok") {

// 拒绝授权

return;

}

if (!this.data.hasLogin) {

wx.showToast({

title: '绑定失败:请先登录',

icon: 'none',

duration: 2000

});

return;

}

util.request(api.AuthBindPhone, {

iv: e.detail.iv,

encryptedData: e.detail.encryptedData

}, 'POST').then(function (res) {

if (res.errno === 0) {

let userInfo = wx.getStorageSync('userInfo');

userInfo.phone = res.data.phone;//设置手机号码

wx.setStorageSync('userInfo', userInfo);

that.setData({

userInfo: userInfo,

hasLogin: true

});

wx.showToast({

title: '绑定手机号码成功',

icon: 'success',

duration: 2000

});

}

});

},

exitLogin: function () {

wx.showModal({

title: '',

confirmColor: '#b4282d',

content: '退出登录?',

success: function (res) {

if (!res.confirm) {

return;

}

util.request(api.AuthLogout, {}, 'POST');

app.globalData.hasLogin = false;

wx.removeStorageSync('token');

wx.removeStorageSync('userInfo');

wx.reLaunch({

url: '/pages/index/index'

});

}

})

}

})

user.wxml

头像

名字

手机号码

ID号

user.wxss  

@import '/static/font/iconfont.wxss';

.personal-data .list {

margin-top: 15rpx;

background-color: #fff;

}

.personal-data .list .item {

padding: 30rpx 30rpx 30rpx 0;

border-bottom: 1rpx solid #f2f2f2;

margin-left: 30rpx;

font-size: 32rpx;

color: #282828;

}

.personal-data .list .item .phone {

background-color: #85c43f;

width: 160rpx;

height: 56rpx;

font-size: 24rpx;

color: #fff;

line-height: 56rpx;

border-radius: 32rpx

}

.personal-data .list .item .pictrue {

width: 88rpx;

height: 88rpx;

}

.personal-data .list .item .pictrue image {

width: 100%;

height: 100%;

border-radius: 50%;

}

.personal-data .list .item .input {

width: 415rpx;

text-align: right;

color: #868686;

}

.personal-data .list .item .input .id {

width: 365rpx;

}

.personal-data .list .item .input .iconfont {

font-size: 35rpx;

}

.personal-data .modifyBnt {

/* background-color: #85c43f; */

/* background: linear-gradient(to left right, #85c43f, #fefefd); */

background: radial-gradient(circle at 50%,#85c43f,#CDDC39);

font-size: 32rpx;

color: #fff;

width: 690rpx;

height: 90rpx;

border-radius: 50rpx;

display: flex;

justify-content: center;

align-items: center;

line-height: 90rpx;

margin: 76rpx auto 0 auto;

}

.acea-row{display:flex;flex-wrap:wrap;}

.acea-row.row-top{align-items:flex-start;}

.acea-row.row-middle{align-items:center;}

.acea-row.row-bottom{align-items:flex-end;}

.acea-row.row-left{justify-content:flex-start;}

.acea-row.row-center{justify-content:center;}

.acea-row.row-right{justify-content:flex-end;}

.acea-row.row-between{justify-content:space-between;}

.acea-row.row-around{justify-content:space-around;}

.acea-row.row-column{flex-direction:column;}

.acea-row.row-column-between{flex-direction:column;justify-content:space-between;}

.acea-row.row-column-around{flex-direction:column;justify-content:space-around;}

.acea-row.row-center-wrapper{align-items:center;justify-content:center;}

.acea-row.row-between-wrapper{align-items:center;justify-content:space-between;}

view, image, text, navigator {

box-sizing: border-box;

padding: 0;

margin: 0;

}

后端代码

在后台编写的控制器,来进行出来前端的请求及数据处理并且反馈带前端

WxAuthController

package com.zking.ssm.wxcontroller;

/**

* @Autho donkee

* @Since 2022/6/27

*/

import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;

import com.alibaba.fastjson.JSONObject;

import com.zking.ssm.annotation.LoginUser;

import com.zking.ssm.model.UserInfo;

import com.zking.ssm.model.WxLoginInfo;

import com.zking.ssm.model.WxUser;

import com.zking.ssm.service.UserToken;

import com.zking.ssm.service.UserTokenManager;

import com.zking.ssm.service.WxUserService;

import com.zking.ssm.util.JacksonUtil;

import com.zking.ssm.util.ResponseUtil;

import com.zking.ssm.util.UserTypeEnum;

import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.util.StringUtils;

import org.springframework.web.bind.annotation.PostMapping;

import org.springframework.web.bind.annotation.RequestBody;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

import cn.binarywang.wx.miniapp.api.WxMaService;

import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;

import javax.servlet.http.HttpServletRequest;

import java.text.DateFormat;

import java.text.SimpleDateFormat;

import java.util.Date;

import java.util.HashMap;

import java.util.Map;

/**

* 鉴权服务

*/

@Slf4j

@RestController

@RequestMapping("/wx/auth")

public class WxAuthController {

@Autowired

private WxMaService wxService;

@Autowired

private WxUserService userService;

/**

* 微信登录

*

* @param wxLoginInfo

* 请求内容,{ code: xxx, userInfo: xxx }

* @param request

* 请求对象

* @return 登录结果

*/

@PostMapping("login_by_weixin")

public Object loginByWeixin(@RequestBody WxLoginInfo wxLoginInfo, HttpServletRequest request) {

//客户端需携带code与userInfo信息

String code = wxLoginInfo.getCode();

UserInfo userInfo = wxLoginInfo.getUserInfo();

if (code == null || userInfo == null) {

return ResponseUtil.badArgument();

}

//调用微信sdk获取openId及sessionKey

String sessionKey = null;

String openId = null;

try {

long beginTime = System.currentTimeMillis();

//

WxMaJscode2SessionResult result = this.wxService.getUserService().getSessionInfo(code);

// Thread.sleep(6000);

long endTime = System.currentTimeMillis();

log.info("响应时间:{}",(endTime-beginTime));

sessionKey = result.getSessionKey();//session id

openId = result.getOpenid();//用户唯一标识 OpenID

} catch (Exception e) {

e.printStackTrace();

}

if (sessionKey == null || openId == null) {

log.error("微信登录,调用官方接口失败:{}", code);

return ResponseUtil.fail();

}else{

log.info("openId={},sessionKey={}",openId,sessionKey);

}

//根据openId查询wx_user表

//如果不存在,初始化wx_user,并保存到数据库中

//如果存在,更新最后登录时间

WxUser user = userService.queryByOid(openId);

if (user == null) {

user = new WxUser();

user.setUsername(openId);

user.setPassword(openId);

user.setWeixinOpenid(openId);

user.setAvatar(userInfo.getAvatarUrl());

user.setNickname(userInfo.getNickName());

user.setGender(userInfo.getGender());

user.setUserLevel((byte) 0);

user.setStatus((byte) 0);

user.setLastLoginTime(new Date());

user.setLastLoginIp(IpUtil.client(request));

user.setShareUserId(1);

userService.add(user);

} else {

user.setLastLoginTime(new Date());

user.setLastLoginIp(IpUtil.client(request));

if (userService.updateById(user) == 0) {

log.error("修改失败:{}", user);

return ResponseUtil.updatedDataFailed();

}

}

// token

UserToken userToken = null;

try {

userToken = UserTokenManager.generateToken(user.getId());

} catch (Exception e) {

log.error("微信登录失败,生成token失败:{}", user.getId());

e.printStackTrace();

return ResponseUtil.fail();

}

userToken.setSessionKey(sessionKey);

log.info("SessionKey={}",UserTokenManager.getSessionKey(user.getId()));

Map result = new HashMap();

result.put("token", userToken.getToken());

result.put("tokenExpire", userToken.getExpireTime().toString());

userInfo.setUserId(user.getId());

if (!StringUtils.isEmpty(user.getMobile())) {// 手机号存在则设置

userInfo.setPhone(user.getMobile());

}

try {

DateFormat df = new SimpleDateFormat("yyyy-MM-dd");

String registerDate = df.format(user.getAddTime() != null ? user.getAddTime() : new Date());

userInfo.setRegisterDate(registerDate);

userInfo.setStatus(user.getStatus());

userInfo.setUserLevel(user.getUserLevel());// 用户层级

userInfo.setUserLevelDesc(UserTypeEnum.getInstance(user.getUserLevel()).getDesc());// 用户层级描述

} catch (Exception e) {

log.error("微信登录:设置用户指定信息出错:"+e.getMessage());

e.printStackTrace();

}

result.put("userInfo", userInfo);

log.info("【请求结束】微信登录,响应结果:{}", JSONObject.toJSONString(result));

return ResponseUtil.ok(result);

}

/**

* 绑定手机号码

*

* @param userId

* @param body

* @return

*/

@PostMapping("bindPhone")

public Object bindPhone(@LoginUser Integer userId, @RequestBody String body) {

log.info("【请求开始】绑定手机号码,请求参数,body:{}", body);

String sessionKey = UserTokenManager.getSessionKey(userId);

String encryptedData = JacksonUtil.parseString(body, "encryptedData");

String iv = JacksonUtil.parseString(body, "iv");

WxMaPhoneNumberInfo phoneNumberInfo = null;

try {

phoneNumberInfo = this.wxService.getUserService().getPhoneNoInfo(sessionKey, encryptedData, iv);

} catch (Exception e) {

log.error("绑定手机号码失败,获取微信绑定的手机号码出错:{}", body);

e.printStackTrace();

return ResponseUtil.fail();

}

String phone = phoneNumberInfo.getPhoneNumber();

WxUser user = userService.selectByPrimaryKey(userId);

user.setMobile(phone);

if (userService.updateById(user) == 0) {

log.error("绑定手机号码,更新用户信息出错,id:{}", user.getId());

return ResponseUtil.updatedDataFailed();

}

Map data = new HashMap();

data.put("phone", phone);

log.info("【请求结束】绑定手机号码,响应结果:{}", JSONObject.toJSONString(data));

return ResponseUtil.ok(data);

}

/**

* 注销登录

*/

@PostMapping("logout")

public Object logout(@LoginUser Integer userId) {

log.info("【请求开始】注销登录,请求参数,userId:{}", userId);

if (userId == null) {

return ResponseUtil.unlogin();

}

try {

UserTokenManager.removeToken(userId);

} catch (Exception e) {

log.error("注销登录出错:userId:{}", userId);

e.printStackTrace();

return ResponseUtil.fail();

}

log.info("【请求结束】注销登录成功!");

return ResponseUtil.ok();

}

}

在 application.yml 文件中进行配置后台的数据库及微信小程序的AppID(微信小程序ID)及AppSecret(微信小程序密钥),来访问微信的接口服务

 效果展示

 今天就到这里了,下班下班!!!!!!!!!

参考阅读

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: