基于小程序库2.10.4版本之前:
此篇文章,针对的是很多看不懂微信官方文档,或者是刚入门小程序和java开发的开发者,教程也会非常详细的讲到我在实现这个功能时碰到的误区,以及详细的介绍整个流程。
在小程序库2.10.4之前,我们利用小程序进行登录时,不做商业处理的情况下,利用java对用户进行处理,我们需要使用到小程序的两个API。实际上用到了三个API,看自己的需求选择。wx.login wx.request wx.getUserProfile(wx.getuserInfo)
提示:以下是本篇文章正文内容,下面案例可供参考
openid作为每个微信用户访问一个小程序时的唯一凭证,这里的openid只是针对一个微信用户和一个小程序,不同的用户针对不同的小程序的openid是不同的,但是一个用户在针对一个小程序登录时,openid是唯一的。

wx.login是小程序的一个API库,可以直接利用js代码调用,每一次获取到的code都是不同的,因为他只是一个登录凭证,
wx.login({ //发起请求
success:(res)=>{ //请求成功赋值给变量
if(res.code){ //变量获取code
wx.request({
url: '', //这里是请求地址
method:'POST', //请求方式
header:{
'content-type':'application/x-www-form-urlencoded', //请求头信息
},
data: {
code: res.code, // 请求参数,login请求到的code
},
success(res){
wx.setStorageSync('token', res.data.data)
}
})
}
}
})
},
fall:res=>{
console.log('失败',res)
}
})
},
那么从前端发送了code过来后,我们从后端能够接收到code,在后端,利用登录凭证校验接口,实现

官方是这样告诉我们的,那么我们就在java后台,调用auth.code2Session接口,换取openid等信息

接口地址:GET https://api.weixin.qq.com/sns/jscode2sessionappid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code
String AppId = ""; //公众平台自己的appId
String AppSecret = ""; //AppSecret
@GetMapping("/login")
public Result<Object> wxLogin(@RequestParam("code") String code) throws Exception {
Result<Object> result = new Result();
String url = "https://api.weixin.qq.com/sns/jscode2session?" +
"appid=" + AppId +
"&secret=" + AppSecret +
"&js_code=" + code +
"&grant_type=authorization_code";
//利用spring原生http请求工具对接口进行请求
String jsonData = restTemplate.getForObject(url, String.class);
JSONObject jsonObject = JSONObject.parseObject(jsonData);
//请求返回的是Json类型的数据 所以我们需要用到fastjson
//这个判断是判断我们的请求是否出错,如果没有出错的话就能够拿到openid
if (StringUtils.contains(jsonData, "errcode")) {
//出错了
result.setMessage("err");
return result;
}
String openid = jsonObject.getString("openid");
String sessionKey = jsonObject.getString("session_key");
String unionid = jsonObject.getString("unionid");
System.out.println(openid);
System.out.println(sessionKey );
System.out.println(unionid);
我们在这里其实已经将用户注册了,拿到openid后,将openid存入到我们的数据库中,openid就作判别一个用户唯一的信息。
在官方后面的流程中,都是对拿到openid后的业务请求,这里就不做过多概述,但是我们发现了一个问题,别人的小程序登录时,都会有头像和名字,我们拿到了openid没有头像和名字,在前端无法展示。这里其实,涉及到了小程序的第三个wx.getUserProfile
在目前的版本中 此API已经更换为新API

由此可见,我们可以通过此API获取到用户的头像和名字的信息
以此类推,我们通过此API获取到用户信息再将信息传递给后端吗? 不 实际上,这样的行为是不安全的。
调用API后,返回给我们的参数中,一个包括敏感数据在内的完整用户信息的加密数据,由此可见,官方将用户信息数据加密给我们了,我们只需要传递加密数据到后端,进行解密,再将数据存入到数据库中就可以了!
代码:
wx.getUserProfile({
desc: '必须授权才能使用',
success:res=>{
let user=res.userInfo
wx.setStorageSync('user', user) //信息暂存在客户端
this.setData({
encryptedData: res.encryptedData,
iv: res.iv
})
wx.request({
url: 'https://mrone.vip/wx/login',
method:'POST',
header:{
'content-type':'application/x-www-form-urlencoded',
},
data: {
encryptedData:encryptedData,
iv:iv,
},
success(res){
wx.setStorageSync('token', res.data.data)
}
})
解密过程代码
@Slf4j
@Component
public class WxService {
@Autowired
private StringRedisTemplate redisTemplate;
//jsonObject 就是利用code 获取到的json对象
public String wxDecrypt(String encryptedData, JSONObject jsonObject, String vi) throws Exception {
// 开始解密
String sessionKey = (String) jsonObject.get("session_key");
byte[] encData = cn.hutool.core.codec.Base64.decode(encryptedData);
byte[] iv = cn.hutool.core.codec.Base64.decode(vi);
byte[] key = Base64.decode(sessionKey);
AlgorithmParameterSpec ivSpec = new IvParameterSpec(iv);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
return new String(cipher.doFinal(encData), "UTF-8");
}
//生成随机用户名,数字和字母组成,
public String getStringRandom(int length) {
StringBuilder val = new StringBuilder();
Random random = new Random();
//参数length,表示生成几位随机数
for (int i = 0; i < length; i++) {
String charOrNum = random.nextInt(2) % 2 == 0 ? "char" : "num";
//输出字母还是数字
if ("char".equalsIgnoreCase(charOrNum)) {
//输出是大写字母还是小写字母
int temp = random.nextInt(2) % 2 == 0 ? 65 : 97;
val.append((char) (random.nextInt(26) + temp));
} else {
val.append(random.nextInt(10));
}
}
return val.toString();
}
}
后端获取参数并进行解密
@RequestMapping("/login")
public Result<Object> wxLogin(String encryptedData, String iv) {
//直接调用解密代码的方法即可
String s = wxService.wxDecrypt(encryptedData, jsonObject, iv);
JSONObject jsonObject1 = JSON.parseObject(s);
Object watermark = jsonObject1.get("watermark");
JSONObject jsonObject2 = JSON.parseObject(String.valueOf(watermark));
//拿到了最后的json对象后,可以输出看看
System.out.println(jsonObject2);
}
那么结合上下文,我们能够将用户进行注册,又能够将用户的信息拿到,那么我们将用户注册登录融为一体,在用户进行登录时就获取信息,并将信息展示到小程序端,将数据存入到数据库,这样就完成了整个微信小程序的登录流程!
(wx.getUserProfile)先获取用户信息=>(wx.login)获取code=>(wx.request)请求后端发送参数=>后端接收解密参数,code,
先利用code进行http请求获取返回的json对象,再利用解密参数和json对象进行解密,获取用户信息,最后存入数据库。
login(){
wx.getUserProfile({
desc: '必须授权才能使用',
success:res=>{
let user=res.userInfo
this.setData({
user:user,
encryptedData: res.encryptedData,
iv: res.iv
})
var encryptedData=res.encryptedData;
var iv=res.iv;
wx.login({
success:(res)=>{
if(res.code){
wx.request({
url: '',
method:'POST',
header:{
'content-type':'application/x-www-form-urlencoded',
},
data: {
code: res.code,
encryptedData:encryptedData,
iv:iv,
},
success(res){
wx.setStorageSync('token', res.data.data)
}
})
}
}
})
},
fall:res=>{
console.log('失败',res)
}
})
},
@RequestMapping("/login")
public Result<Object> wxLogin(@RequestParam("code") String code, String encryptedData, String iv) throws Exception {
Result<Object> result = new Result();
String url = "https://api.weixin.qq.com/sns/jscode2session?" +
"appid=" + AppId +
"&secret=" + AppSecret +
"&js_code=" + code +
"&grant_type=authorization_code";
//获取返回的数据 并将数据转换成json对象
String jsonData = restTemplate.getForObject(url, String.class);
JSONObject jsonObject = JSONObject.parseObject(jsonData);
if (StringUtils.contains(jsonData, "errcode")) {
//出错了
result.setMessage("err");
return result;
}
String openid = jsonObject.getString("openid");
String sessionKey = jsonObject.getString("session_key");
//解密
String s = wxService.wxDecrypt(encryptedData, jsonObject, iv);
JSONObject jsonObject1 = JSON.parseObject(s);
Object watermark = jsonObject1.get("watermark");
JSONObject jsonObject2 = JSON.parseObject(String.valueOf(watermark));
–
提示:下一次会更新最新的小程序信息方法:
此次教程是针对于还未更新的方法,教程非常详细,希望能够帮助到你。
这里附带上我的微信小程序开源项目:
项目地址:https://github.com/CaseOfShe/school
演示地址:https://www.bilibili.com/video/BV1q3411g71P
深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
小编已加密:aHR0cHM6Ly9kb2NzLnFxLmNvbS9kb2MvRFVrVm9aSGxQZUVsTlkwUnc==出于安全原因,我们把网站通过base64编码了,大家可以通过base64解码把网址获取下来。
导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
在VMware16.2.4安装Ubuntu一、安装VMware1.打开VMwareWorkstationPro官网,点击即可进入。2.进入后向下滑动找到Workstation16ProforWindows,点击立即下载。3.下载完成,文件大小615MB,如下图:4.鼠标右击,以管理员身份运行。5.点击下一步6.勾选条款,点击下一步7.先勾选,再点击下一步8.去掉勾选,点击下一步9.点击下一步10.点击安装11.点击许可证12.在百度上搜索VM16许可证,复制填入,然后点击输入即可,亲测有效。13.点击完成14.重启系统,点击是15.双击VMwareWorkstationPro图标,进入虚拟机主
前言一般来说,前端根据后台返回code码展示对应内容只需要在前台判断code值展示对应的内容即可,但要是匹配的code码比较多或者多个页面用到时,为了便于后期维护,后台就会使用字典表让前端匹配,下面我将在微信小程序中通过wxs的方法实现这个操作。为什么要使用wxs?{{method(a,b)}}可以看到,上述代码是一个调用方法传值的操作,在vue中很常见,多用于数据之间的转换,但由于微信小程序诸多限制的原因,你并不能优雅的这样操作,可能有人会说,为什么不用if判断实现呢?但是if判断的局限性在于如果存在数据量过大时,大量重复性操作和if判断会让你的代码显得异常冗余。wxswxs相当于是一个独立
项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU
@作者:SYFStrive @博客首页:HomePage📜:微信小程序📌:个人社区(欢迎大佬们加入)👉:社区链接🔗📌:觉得文章不错可以点点关注👉:专栏连接🔗💃:感谢支持,学累了可以先看小段由小胖给大家带来的街舞👉微信小程序(🔥)目录自定义组件-behaviors 1、什么是behaviors 2、behaviors的工作方式 3、创建behavior 4、导入并使用behavior 5、behavior中所有可用的节点 6、同名字段的覆盖和组合规则总结最后自定义组件-behaviors 1、什么是behaviorsbehaviors是小程序中,用于实现
需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc
我正在寻找用于Rails的优质管理插件。似乎大多数现有的插件/gem(例如“restful_authentication”、“acts_as_authenticated”)都围绕着self注册等展开。但是,我正在寻找一种功能齐全的基于管理/管理角色的解决方案——但不是简单地附加到另一个非基于角色的解决方案。如果我找不到,我想我会自己动手......只是不想重新发明轮子。 最佳答案 RyanBates最近做了两个关于授权的railscast(注意身份验证和授权之间的区别;身份验证检查用户是否如她所说的那样,授权检查用户是否有权访问资源
我需要从站点抓取数据,但它需要我先登录。我一直在使用hpricot成功地抓取其他网站,但我是使用mechanize的新手,我真的对如何使用它感到困惑。我看到这个例子经常被引用:require'rubygems'require'mechanize'a=Mechanize.newa.get('http://rubyforge.org/')do|page|#Clicktheloginlinklogin_page=a.click(page.link_with(:text=>/LogIn/))#Submittheloginformmy_page=login_page.form_with(:act
我正在根据Rakefile中的现有测试文件动态生成测试任务。假设您有各种以模式命名的单元测试文件test_.rb.所以我正在做的是创建一个以“测试”命名空间内的文件名命名的任务。使用下面的代码,我可以用raketest:调用所有测试require'rake/testtask'task:default=>'test:all'namespace:testdodesc"Runalltests"Rake::TestTask.new(:all)do|t|t.test_files=FileList['test_*.rb']endFileList['test_*.rb'].eachdo|task|n