springboot实现微信小程序授权登录前后端代码完整版

       一个简单的微信授权登录的demo,我这边没有建表,是存到redis里面了,仅供参考,后续可以扩展自己的业务逻辑,把登录信息存在表里面。

  • 前端小程序代码:

<view><view class="login-icon"><image class="login-img" src="../resource/images/dsp.jpg"></image></view><view class="login-from"><form bindsubmit='doLogin'><!--账号--><view class="inputView"><image class="nameImage" src="../resource/images/username.png"></image><label class="loginLabel">账号</label><input name="username" value='imooc' class="inputText" placeholder="请输入账号" /></view><view class="line"></view><!--密码--><view class="inputView"><image class="keyImage" src="../resource/images/password.png"></image><label class="loginLabel">密码</label><input name="password" value='imooc' class="inputText" password="true" placeholder="请输入密码" /></view><!--按钮--><view><button class="loginBtn" type="primary">普通登录</button></view><view><button class="goRegistBtn" type="warn" open-type='getUserInfo' bindgetuserinfo='doLogin'>微信登录</button></view></form></view>
</view>
page {background-color: whitesmoke;
}.login-img {width: 750rpx;
}/*表单内容*/
.inputView {background-color: white;line-height: 45px;
}/*输入框*/
.nameImage, .keyImage {margin-left: 22px;width: 20px;height: 20px;
}.loginLabel {margin: 15px 15px 15px 10px;color: gray;font-size: 15px;
}.inputText {float: right;text-align: right;margin-right: 22px;margin-top: 11px;font-size: 15px;
}.line {width: 100%;height: 1px;background-color: gainsboro;margin-top: 1px;
}/*按钮*/
.loginBtn {width: 80%;margin-top: 35px;
}.goRegistBtn {width: 80%;margin-top: 15px;
}
const app = getApp()Page({data: {},onLoad: function (params) {},// 登录  doLogin: function (e) {console.log(e.detail.errMsg)console.log(e.detail.userInfo)console.log(e.detail.rawData)wx.login({success: function(res) {console.log(res)// 获取登录的临时凭证var code = res.code;// 调用后端,获取微信的session_key, secretwx.request({url: "http://127.0.0.1:8080/wxLogin?code=" + code,method: "POST",success: function(result) {console.log(result);// 保存用户信息到本地缓存,可以用作小程序端的拦截器app.setGlobalUserInfo(e.detail.userInfo);wx.redirectTo({//成功后跳转到首页url: '../index/index',})}})}})}
})
  • 后端代码:

public class WXSessionModel {private String session_key;private String openid;public String getSession_key() {return session_key;}public void setSession_key(String session_key) {this.session_key = session_key;}public String getOpenid() {return openid;}public void setOpenid(String openid) {this.openid = openid;}
}
import java.util.HashMap;
import java.util.Map;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;import com.fasterxml.jackson.databind.annotation.JsonAppend.Attr;
import com.test.common.HttpClientUtil;
import com.test.common.IMoocJSONResult;
import com.test.common.JsonUtils;
import com.test.common.RedisOperator;
import com.test.model.WXSessionModel;@RestController
public class WXLoginController {@Autowiredprivate RedisOperator redis;@PostMapping("/wxLogin")public JSONResult wxLogin(String code) {System.out.println("wxlogin - code: " + code);//		https://api.weixin.qq.com/sns/jscode2session?
//				appid=APPID&
//				secret=SECRET&
//				js_code=JSCODE&
//				grant_type=authorization_codeString url = "https://api.weixin.qq.com/sns/jscode2session";Map<String, String> param = new HashMap<>();param.put("appid", "换成自己的appid");param.put("secret", "换成自己的secret");param.put("js_code", code);param.put("grant_type", "authorization_code");String wxResult = HttpClientUtil.doGet(url, param);System.out.println(wxResult);WXSessionModel model = JsonUtils.jsonToPojo(wxResult, WXSessionModel.class);// 存入session到redisredis.set("user-redis-session:" + model.getOpenid(), model.getSession_key(), 1000 * 60 * 30);return IMoocJSONResult.ok();}}
  • 工具类:

import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;public class HttpClientUtil {public static String doGet(String url, Map<String, String> param) {// 创建Httpclient对象CloseableHttpClient httpclient = HttpClients.createDefault();String resultString = "";CloseableHttpResponse response = null;try {// 创建uriURIBuilder builder = new URIBuilder(url);if (param != null) {for (String key : param.keySet()) {builder.addParameter(key, param.get(key));}}URI uri = builder.build();// 创建http GET请求HttpGet httpGet = new HttpGet(uri);// 执行请求response = httpclient.execute(httpGet);// 判断返回状态是否为200if (response.getStatusLine().getStatusCode() == 200) {resultString = EntityUtils.toString(response.getEntity(), "UTF-8");}} catch (Exception e) {e.printStackTrace();} finally {try {if (response != null) {response.close();}httpclient.close();} catch (IOException e) {e.printStackTrace();}}return resultString;}public static String doGet(String url) {return doGet(url, null);}public static String doPost(String url, Map<String, String> param) {// 创建Httpclient对象CloseableHttpClient httpClient = HttpClients.createDefault();CloseableHttpResponse response = null;String resultString = "";try {// 创建Http Post请求HttpPost httpPost = new HttpPost(url);// 创建参数列表if (param != null) {List<NameValuePair> paramList = new ArrayList<>();for (String key : param.keySet()) {paramList.add(new BasicNameValuePair(key, param.get(key)));}// 模拟表单UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList);httpPost.setEntity(entity);}// 执行http请求response = httpClient.execute(httpPost);resultString = EntityUtils.toString(response.getEntity(), "utf-8");} catch (Exception e) {e.printStackTrace();} finally {try {response.close();} catch (IOException e) {e.printStackTrace();}}return resultString;}public static String doPost(String url) {return doPost(url, null);}public static String doPostJson(String url, String json) {// 创建Httpclient对象CloseableHttpClient httpClient = HttpClients.createDefault();CloseableHttpResponse response = null;String resultString = "";try {// 创建Http Post请求HttpPost httpPost = new HttpPost(url);// 创建请求内容StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);httpPost.setEntity(entity);// 执行http请求response = httpClient.execute(httpPost);resultString = EntityUtils.toString(response.getEntity(), "utf-8");} catch (Exception e) {e.printStackTrace();} finally {try {response.close();} catch (IOException e) {e.printStackTrace();}}return resultString;}
}
/*** @Description: 自定义响应数据结构* 				这个类是提供给门户,ios,安卓,微信商城用的* 				门户接受此类数据后需要使用本类的方法转换成对于的数据类型格式(类,或者list)* 				其他自行处理* 				200:表示成功* 				500:表示错误,错误信息在msg字段中* 				501:bean验证错误,不管多少个错误都以map形式返回* 				502:拦截器拦截到用户token出错* 				555:异常抛出信息*/
public class JSONResult {// 响应业务状态private Integer status;// 响应消息private String msg;// 响应中的数据private Object data;private String ok;	// 不使用public static JSONResult build(Integer status, String msg, Object data) {return new JSONResult(status, msg, data);}public static JSONResult ok(Object data) {return new JSONResult(data);}public static JSONResult ok() {return new JSONResult(null);}public static JSONResult errorMsg(String msg) {return new JSONResult(500, msg, null);}public static JSONResult errorMap(Object data) {return new JSONResult(501, "error", data);}public static JSONResult errorTokenMsg(String msg) {return new JSONResult(502, msg, null);}public static JSONResult errorException(String msg) {return new JSONResult(555, msg, null);}public JSONResult() {}public JSONResult(Integer status, String msg, Object data) {this.status = status;this.msg = msg;this.data = data;}public JSONResult(Object data) {this.status = 200;this.msg = "OK";this.data = data;}public Boolean isOK() {return this.status == 200;}public Integer getStatus() {return status;}public void setStatus(Integer status) {this.status = status;}public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}public Object getData() {return data;}public void setData(Object data) {this.data = data;}public String getOk() {return ok;}public void setOk(String ok) {this.ok = ok;}}
import java.util.List;import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;/*** * @Description: 自定义响应结构, 转换类*/
public class JsonUtils {// 定义jackson对象private static final ObjectMapper MAPPER = new ObjectMapper();/*** 将对象转换成json字符串。* <p>Title: pojoToJson</p>* <p>Description: </p>* @param data* @return*/public static String objectToJson(Object data) {try {String string = MAPPER.writeValueAsString(data);return string;} catch (JsonProcessingException e) {e.printStackTrace();}return null;}/*** 将json结果集转化为对象* * @param jsonData json数据* @param clazz 对象中的object类型* @return*/public static <T> T jsonToPojo(String jsonData, Class<T> beanType) {try {T t = MAPPER.readValue(jsonData, beanType);return t;} catch (Exception e) {e.printStackTrace();}return null;}/*** 将json数据转换成pojo对象list* <p>Title: jsonToList</p>* <p>Description: </p>* @param jsonData* @param beanType* @return*/public static <T>List<T> jsonToList(String jsonData, Class<T> beanType) {JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType);try {List<T> list = MAPPER.readValue(jsonData, javaType);return list;} catch (Exception e) {e.printStackTrace();}return null;}}
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;/*** @Description: 使用redisTemplate的操作实现类 */
@Component
public class RedisOperator {//	@Autowired
//    private RedisTemplate<String, Object> redisTemplate;@Autowiredprivate StringRedisTemplate redisTemplate;// Key(键),简单的key-value操作/*** 实现命令:TTL key,以秒为单位,返回给定 key的剩余生存时间(TTL, time to live)。* * @param key* @return*/public long ttl(String key) {return redisTemplate.getExpire(key);}/*** 实现命令:expire 设置过期时间,单位秒* * @param key* @return*/public void expire(String key, long timeout) {redisTemplate.expire(key, timeout, TimeUnit.SECONDS);}/*** 实现命令:INCR key,增加key一次* * @param key* @return*/public long incr(String key, long delta) {return redisTemplate.opsForValue().increment(key, delta);}/*** 实现命令:KEYS pattern,查找所有符合给定模式 pattern的 key*/public Set<String> keys(String pattern) {return redisTemplate.keys(pattern);}/*** 实现命令:DEL key,删除一个key* * @param key*/public void del(String key) {redisTemplate.delete(key);}// String(字符串)/*** 实现命令:SET key value,设置一个key-value(将字符串值 value关联到 key)* * @param key* @param value*/public void set(String key, String value) {redisTemplate.opsForValue().set(key, value);}/*** 实现命令:SET key value EX seconds,设置key-value和超时时间(秒)* * @param key* @param value* @param timeout*            (以秒为单位)*/public void set(String key, String value, long timeout) {redisTemplate.opsForValue().set(key, value, timeout, TimeUnit.SECONDS);}/*** 实现命令:GET key,返回 key所关联的字符串值。* * @param key* @return value*/public String get(String key) {return (String)redisTemplate.opsForValue().get(key);}// Hash(哈希表)/*** 实现命令:HSET key field value,将哈希表 key中的域 field的值设为 value* * @param key* @param field* @param value*/public void hset(String key, String field, Object value) {redisTemplate.opsForHash().put(key, field, value);}/*** 实现命令:HGET key field,返回哈希表 key中给定域 field的值* * @param key* @param field* @return*/public String hget(String key, String field) {return (String) redisTemplate.opsForHash().get(key, field);}/*** 实现命令:HDEL key field [field ...],删除哈希表 key 中的一个或多个指定域,不存在的域将被忽略。* * @param key* @param fields*/public void hdel(String key, Object... fields) {redisTemplate.opsForHash().delete(key, fields);}/*** 实现命令:HGETALL key,返回哈希表 key中,所有的域和值。* * @param key* @return*/public Map<Object, Object> hgetall(String key) {return redisTemplate.opsForHash().entries(key);}// List(列表)/*** 实现命令:LPUSH key value,将一个值 value插入到列表 key的表头* * @param key* @param value* @return 执行 LPUSH命令后,列表的长度。*/public long lpush(String key, String value) {return redisTemplate.opsForList().leftPush(key, value);}/*** 实现命令:LPOP key,移除并返回列表 key的头元素。* * @param key* @return 列表key的头元素。*/public String lpop(String key) {return (String)redisTemplate.opsForList().leftPop(key);}/*** 实现命令:RPUSH key value,将一个值 value插入到列表 key的表尾(最右边)。* * @param key* @param value* @return 执行 LPUSH命令后,列表的长度。*/public long rpush(String key, String value) {return redisTemplate.opsForList().rightPush(key, value);}}
  • pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.test</groupId><artifactId>test-springboot-wxlogin</artifactId><version>0.0.1-SNAPSHOT</version><packaging>war</packaging><name>test-springboot-wxlogin</name><description>test-springboot-wxlogin</description><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.5.12.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId><exclusions><!-- 排除springboot默认的logback日志框架 --><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></exclusion></exclusions></dependency><!-- 引入log4j日志依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-log4j</artifactId><version>1.3.8.RELEASE</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId><scope>provided</scope></dependency><!-- apache 工具类 --><dependency><groupId>commons-codec</groupId><artifactId>commons-codec</artifactId><version>1.11</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.4</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-io</artifactId><version>1.3.2</version></dependency><!-- 引入 redis 依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>2.9.0</version></dependency><dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-redis</artifactId><version>1.8.7.RELEASE</version></dependency><!-- httpclient --><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.3.5</version></dependency></dependencies></project>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/629869.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ABAP - 读取长文本优化

做程序优化的时候发现在循环里面读取长文本&#xff0c;用&#xff08;READ_TEXT\类的方法&#xff09;读取太消耗性能了&#xff0c;于是用读取底表的方法去取。 DATA lt_stxl_raw TYPE TABLE OF ty_stxl_raw.DATA ls_stxl_raw TYPE ty_stxl_raw.DATA lt_tline TY…

MFC为资源对话框添加消息处理函数和初始化控件

现在我VC6新建了一个对话框工程&#xff1b;又在资源添加了一个新的对话框&#xff0c;并为新的对话框添加了名为CTestDlg的类&#xff1b; 在主对话框的cpp文件包含#include "TestDlg.h"&#xff1b; 在主对话框的cpp文件的OnInitDialog()成员函数中&#xff0c;添…

算法之回溯动态规划贪心

回溯使用场景&#xff1a;求出所有可能的解。 List result; void backtrack(路径,选择列表){if(满足结束条件){result.add(路径);return;}for(选择:选择列表){// 遍历集合中的元素做选择;backtrack(路径,选择列表);撤销选择;} }动态规划使用场景&#xff1a;寻求最优解。 #初…

单列的堆叠柱状图

目的 MSingleColumnStackBarChart类被设计用于创建只有单列的堆叠柱状图&#xff0c;用于血糖数据的统计。以下是封装这个类的目的的详细描述&#xff1a; 抽象复杂性&#xff1a; 通过创建MSingleColumnStackBarChart类&#xff0c;你将复杂的MPAndroidChart库的使用和配置封…

12166 - Equilibrium Mobile (UVA)

题目链接如下&#xff1a; Online Judge 一个很简洁的写法&#xff1a;UVa 12166 Equilibrium Mobile——思路题_equilibrium mobile uva - 12166-CSDN博客 才33行&#xff0c;真的NB坏了…… 我的比较繁琐的代码&#xff08;能AC&#xff09;&#xff0c;比较之下就能发现…

VUE---组件的样式冲突scoped

默认情况 &#xff1a;写在组件中的样式会 全局生效 &#xff0c;因此很容易造成多个组件之间的样式冲突问题。 1、 全局样式 &#xff1a; 默认组件中的样式会作用到全局 2、 局部样式 &#xff1a; 可以给组件加上 scoped 属性&#xff0c; 让样式只作用于当前组件 sc…

FastGPT + Xinference + OneAPI:一站式本地 LLM 私有化部署和应用开发

Excerpt 随着 GPTs 的发布,构建私有知识库变得无比简易,这为个人创建数字化身份、第二大脑,或是企业建立知识库,都提供了全新的途径。然而,基于众所周知的原因,GPTs 在中国的使用依然存在诸多困扰和障碍。因此,在当… 随着 GPTs 的发布,构建私有知识库变得无比简易,这…

React全局状态管理

redux是一个状态管理框架&#xff0c;它可以帮助我们清晰定义state和处理函数&#xff0c;提高可读性&#xff0c;并且redux中的状态是全局共享&#xff0c;规避组件间通过props传递状态等操作。 快速使用 在React应用的根节点&#xff0c;需要借助React的Context机制存放整个…

深入探讨 Go 语言中的 Map 类型

深入探讨 Go 语言中的 Map 类型 Go 语言中的 map 类型是一种非常强大且常用的数据结构&#xff0c;它提供了一种键值对的映射关系。本篇博客将深入讨论 Go 中的 map 类型&#xff0c;包括其基本用法、特性、以及一些最佳实践。 基本概念 1. 声明和初始化 在 Go 中&#xff…

mobi文件怎么转换成pdf?

mobi文件怎么转换成pdf&#xff1f;在数字化时代&#xff0c;电子书籍成为了越来越受欢迎的阅读方式。我们可以通过多种格式的电子书来获取知识和娱乐&#xff0c;其中一种常见的格式就是Mobi文件。Mobi文件是亚马逊公司开发的一种电子书格式&#xff0c;它主要用于Kindle设备和…

SL4010升压恒压电源芯片DC3.7V升压5V、12V、24V/5A

SL4010是一款升压恒压电源芯片&#xff0c;可以将DC3.7V的输入电压升压至5V、12V或24V的输出电压&#xff0c;并可提供高达5A的输出电流。这款芯片采用了先进的升压技术&#xff0c;能够实现高效、稳定的电压转换&#xff0c;同时还具有低噪声、低功耗和低成本等优点。在各种需…

【论文阅读】Consistency Models

文章目录 IntroductionDiffusion ModelsConsistency ModelsDefinitionParameterizationSampling Training Consistency Models via DistillationTraining Consistency Models in IsolationExperiment Introduction 相比于单步生成的模型&#xff08;例如 GANs, VAEs, normalizi…

推荐几个Github高星GoLang管理系统

在Web开发领域&#xff0c;Go语言&#xff08;Golang&#xff09;以其高效、简洁、高并发等特性逐渐成为许多开发者的首选语言。有许多优秀的Go语言Web后台管理系统&#xff0c;这些项目星星众多&#xff0c;提供了丰富的功能和良好的代码质量。本文将介绍一些GitHub高星的GoLa…

学会这个昼夜系统,你也能做出一款饥荒生存类游戏DEMO!

学会这个昼夜系统&#xff0c;你也能做出一款饥荒生存类游戏DEMO&#xff01; 《饥荒》作为生存类游戏的老大哥&#xff0c;深受大家喜爱&#xff0c;这款游戏于2012年年底正式公测上线&#xff0c;距今已有10年的时间&#xff0c;从最初的单机版慢慢推出了联机版&#xff0c;…

Android平台Unity下如何通过WebCamTexture采集摄像头数据并推送至RTMP服务器或轻量级RTSP服务

技术背景 我们在对接Unity下推送模块的时候&#xff0c;遇到这样的技术诉求&#xff0c;开发者希望在Android的Unity场景下&#xff0c;获取到前后摄像头的数据&#xff0c;并投递到RTMP服务器&#xff0c;实现低延迟的数据采集处理。 在此之前&#xff0c;我们已经有了非常成…

大模型学习之书生·浦语大模型5——基于LMDeploy大模型量化部署实践

目录 大模型部署背景 LMDeploy部署 量化 TurboMind API server 动手实践环节

LCR 173. 点名(二分)

一、题目描述 LCR 173. 点名 某班级 n 位同学的学号为 0 ~ n-1。点名结果记录于升序数组 records。假定仅有一位同学缺席&#xff0c;请返回他的学号。 示例 1: 输入: records [0,1,2,3,5] 输出: 4示例 2: 输入: records [0, 1, 2, 3, 4, 5, 6, 8] 输出: 7 二、题目解析…

flink1.14.5使用CDH6.3.2的yarn提交作业

使用CDH6.3.2安装了hadoop集群&#xff0c;但是CDH不支持flink的安装&#xff0c;网上有CDH集成flink的文章&#xff0c;大都比较麻烦&#xff1b;但其实我们只需要把flink的作业提交到yarn集群即可&#xff0c;接下来以CDH yarn为基础&#xff0c;flink on yarn模式的配置步骤…

2024-01-16 创业日记-关于用户需求分析-思考

摘要: 创业公司一个非常大的问&#xff0c;就是制造的产品没有市场。创始人所设想的需求&#xff0c;不是真正的市场上所缺失的&#xff0c;导致开发出的产品不被市场认可。 那么需求是如何确定的呢&#xff1f;需求是怎么来的呢&#xff1f;自己所设想的用户需求&#xff0c…

时间函数 localtime localtime_r

时间函数 localtime localtime_r localtime 和 localtime_r 的函数功能&#xff1a; converts the calendar time timep to broken-time representation 在调用 localtime 和 localtime_t 函数时&#xff0c;需特别注意&#xff1a; localtime 是不可重入函数&#xff0c;非线…