Spring Boot实现微信小程序登录

网友投稿 310 2023-01-19

Spring Boot实现微信小程序登录

使用Spring Boot完成微信小程序登录

由于微信最近的版本更新,wx.getUserInfo()的这个接口即将失效,将用wx.getUserProfile()替换,所以近期我也对自己的登录进行更新,并且为了巩固学习到的知识,我自己做了一个小demo,在此分享给大家,希望能对大家有所帮助。废话不多说,直接上代码。

前端

.wxml

js部分

bindGetUserInfo(e) {

let that = this

let token = wx.getStorageSync('token'); //token其实就是后台调用微信登录接口返回的openid,每个用户在同一个小程序内是唯一的。

wx.showLoading({

title: '加载中', //提示框,加载中的样式

})

if (token) {

//如果已经有token,说明用户已经登录,跳转到指定页面

wx.switchTab({

url: ''

})

} else {

//用户还未登录,申请用户授权

wx.getUserProfile({

desc: '用于完善会员资料', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写

succhttp://ess: (res) => {

that.setData({

userInfo: res.userInfo, //保存用户信息

})

if (res.errMsg == "getUserProfile:ok") {

let code = null

wx.login({

success: function (e) {

code = e.code

let params = {};

params.code = code; //用户code 注:用户的code每次登录都是随机的,所以不需要进行存储

params.avatarUrl = res.userInfo.avatarUrl; //用户头像

params.nickName = res.userInfo.nickName; //用户微信名

params.gender = res.userInfo.gender; //用户性别 0为未知,1为男,2为女

//还有有用户微信设置的地址信息,个人认为没啥用,所以没处理

wx.request({

url: '', //后台接口

data: params,

method: 'POST',

header: {

'Content-Type': 'application/json',

'X-Nideshop-Token': wx.getStorageSync('token')

},

success: function (res) { //URL为你后台的接口

console.log(res)

if (res.data.code === 200) {

//存储用户信息

wx.setStorageSync('userInfo', res.data.userInfo);

wx.setStorageSync('token', res.data.userInfo.openId);

wx.switchTab({

url: '' //跳转到指定页面

})

wx.hideLoading() //关闭提示框

} else {

//输出错误信息

}

}

})

}

})

} else {

//用户按了拒绝按钮

wx.showModal({

title: '警告通知',

content: '您点击了拒绝授权,将无法正常显示个人信息,点击确定重新获取授权。',

success: function (res) {

//用户拒绝登录后的处理

}

});

}

}

})

}

},

前台的部分都在这了,详细的解释都写在注释里了,如果多处使用登录、或者校验用户是否登录,建议进行封装,方便调用。

后台

后台部分我使用的是springboot框架,为了方便新手学习,我会将整个模块贴在后面,包括jar包。

首先给大家看一下项目目录结构

POM.XML

jar包的内容并不复杂,我相信各位应该都没啥问题哈哈哈哈哈

com.alibaba

fastjson

1.2.47

mysql

mysql-connector-java

8.0.23

org.springframework.boot

spring-boot-starter-web

2.4.4

com.alibaba

druid

1.1.10

org.mybatis.spring.boot

mybatis-spring-boot-starter

2.1.4

log4j

log4j

1.2.17

org.projectlombok

lombok

1.16.18

配置类 application.yml

配置类的内容也不复杂,在此就不作解释啦

mybatis:

type-aliases-package: com.cxb.pojo

config-location: classpath:mybatis/mybatis-config.xml

mapper-locations: classpath:mybatis/mapper/*.xml

spring:

application:

name: item

#数据库部分

datasource:

type: com.alibaba.druid.pool.DruidDataSource

driver-class-name: com.mysql.cj.jdbc.Driver

url: jdbc:mysql:///item?useUnicode=treu&charactEncoding=utf-8

username: root

password: 123456

wxMini:

appId: #小程序的appid,在哪获取如果不知道的话可以百度哟

secret: #小程序密匙

mybatis-config.xml

PUBLIC "-//mybatis.org//DTD Config 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-config.dtd">

工具类 WeChatUtil

这个工具类是我网上找的一个比较简单的工具类,因为微信登录接口返回的参数是加密的,所以需要解密

package com.cxb.utils;

import com.alibaba.fastjson.JSONObject;

import lombok.extern.slf4j.Slf4j;

import javax.net.ssl.HttpsURLConnection;

import java.io.*;

import java.net.URL;

import java.net.URLConnection;

import java.nio.charset.StandardCharsets;

/**

* 微信小程序工具类

*/

@Slf4j

public class WeChatUtil {

public static String httpRequest(String requestUrl, String requestMethod, String output) {

try {

URL url = new URL(requestUrl);

HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();

connection.setDoOutput(true);

connection.setDoInput(true);

connection.setUseCaches(false);

connection.setRequestMethod(requestMethod);

if (null != output) {

OutputStream outputStream = connection.getOutputStream();

outputStream.write(output.getBytes(StandardCharsets.UTF_8));

outputStream.close();

}

// 从输入流读取返回内容

InputStream inputStream = connection.getInputStream();

InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);

BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

String str;

StringBuilder buffer = new StringBuilder();

while ((str = bufferedReader.readLine()) != null) {

buffer.append(str);

}

bufferedReader.close();

inputStreamReader.close();

inputStream.close();

connection.disconnect();

return buffer.toString();

} catch (Exception e) {

e.printStackTrace();

}

return "";

}

/**

* 向指定 URL 发送POST方法的请求

*

* @param url 发送请求的 URL

* @param json 请求参数,请求参数应该是 json 的形式。

* @return 所代表远程资源的响应结果

*/

public static String httpPost(String url, JSONObject json) {

PrintWriter out = null;

BufferedReader in = null;

String result = "";

try {

URL realUrl = new URL(url);

// 打开和URL之间的连接

URLConnection conn = realUrl.openConnection();

// 设置通用的请求属性

conn.setRequestProperty("accept", "*/*");

conn.setRequestProperty("connection", "Keep-Alive");

conn.setRequestProperty("user-agent",

"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");

// 发送POST请求必须设置如下两行

conn.setDoOutput(true);

conn.setDoInput(true);

// 获取URLConnection对象对应的输出流

out = new PrintWriter(conn.getOutputStream());

// 发送请求参数

out.print(json);

// flush输出流的缓冲

out.flush();

// 定义BufferedReader输入流来读取URL的响应

in = new BufferedReader(

new InputStreamReader(conn.getInputStream()));

String line;

while ((line = in.readLine()) != null) {

result=result.concat(line);

}

} catch (Exception e) {

System.out.println("发送 POST 请求出现异常!" + e);

e.printStackTrace();

}

//使用finally块来关闭输出流、输入流

finally {

try {

if (out != null) {

out.close();

}

if (in != null) {

in.close();

}

} catch (IOException ex) {

ex.printStackTrace();

}

}

return result;

}

}

接下来就是项目的主题代码了,因为只是做一个简单的demo,所以内容并不复杂,但是不管是学习还是普通的小项目都是没有问题的,可以放心使用

Dao层 UserDao

package com.cxb.dao;

import com.cxb.pojo.User;

import org.apache.ibatis.annotations.Mapper;

imcssloSKgport org.springframework.stereotype.Repository;

@Mapper

@Repository

public interface UserDao {

User queryById(String openId);

void insertUser(User user);

void updateUser(User user);

}

service层 UserService

package com.cxb.service;

import com.cxb.dao.UserDao;

import com.cxb.pojo.User;

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

import org.springframework.stereotype.Service;

@Service

public class UserService implements UserDao {

@Autowired

private UserDao userDao;

@Override

public User queryById(String openId) {

return userDao.queryById(openId);

}

@Override

public void insertUser(User user) {

userDao.insertUser(user);

}

@Override

public void updateUser(User user) {

userDao.updateUser(user);

}

}

实体类 User

package com.cxb.pojo;

import lombok.AllArgsConstructor;

import lombok.Data;

import lombok.NoArgsConstructor;

import lombok.experimental.Accessors;

import java.io.Serializable;

import java.util.Date;

@Data

@NoArgsConstructor

@Accessors(chain = true)

public class User implements Serializable {

private Long id; //id

private String code; //只是为了能接收参数,不需要存入数据库

private String openId; //微信登录接口返回的参数之一,就是token

private String nickName; //微信名

private String avatarUrl; //头像

private String gender; //性别 0 未知 1 男 2 女

private Date firstLoginTime; //第一次登录时间

private Date lastLoginTime; //最后一次登录时间

}

SQL部分 UserMapper.xml

PUBLIC "-//mybatis.org//DTD Mapepr 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

select * from user where open_id = #{openId}

insert into user (

open_id,

nick_name,

avatar_url,

gender,

first_login_time,

last_login_time

)

values(

#{openId},

#{nickName},

#{avatarUrl},

#{gender},

#{firstLoginTime},

#{lastLoginTime}

)

update user

`nick_name` = #{nickName},

`avatar_url` = #{avatarUrl},

`gender` = #{gender},

`last_login_time` = #{lastLoginTime}

where id = #{id}

控制器 UserController

package com.cxb.controller;

import com.alibaba.fastjson.JSONObject;

import com.cxb.pojo.User;

import com.cxb.service.UserService;

import com.cxb.utils.WeChatUtil;

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

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

import org.springframework.stereotype.Controller;

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

import java.util.Date;

@Controller

@RequestMapping(value = "/user")

public class UserController {

@Value("${wxMini.appId}")

public String appId;

@Value("${wxMini.secret}")

public String secret;

@Autowired

private UserService userService;

@RequestMapping(value = "/login",method = RequestMethod.POST)

@ResponseBody

public JSONObject login(@RequestBody User user){

String code = user.getCode();

JSONObject object=new JSONObject();

if(code == "" || "".equals(code)){

object.put("code",300);

object.put("msg","code不能为空!");

return object;

}

else {

//微信接口服务,通过调用微信接口服务中jscode2session接口获取到openid和session_key

String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + appId + "&secret=" + secret + "&js_code=" + code + "&grant_type=authorization_code";

String str = WeChatUtil.httpRequest(url, "GET", null); //调用工具类解密

JSONObject jsonObject=JSONObject.parseObject(str);

String openid = (String) jsonObject.get("openid");

if(openid != null && !"".equals(openid)){

//登录成功

User userVo=new User();

userVo.setNickName(user.getNickName());

userVo.setAvatarUrl(user.getAvatarUrl());

userVo.setOpenId(openid);

cssloSKg userVo.setGender(user.getGender());

userVo.setFirstLoginTime(new Date(System.currentTimeMillis()));

userVo.setLastLoginTime(new Date(System.currentTimeMillis()));

User us = userService.queryById(openid);

if(us != null) {

//不是首次登录,更新用户信息

userVo.setId(us.getId());

userService.updateUser(userVo);

}

else {

//首次登录,存储用户信息

userService.insertUser(userVo);

}

object.put("code",200);

object.put("msg","登录成功!");

object.put("userInfo",userVo);

return object;

}else {

object.put("code",400);

object.put("msg","未知错误,请重试!");

return object;

}

}

}

}

启动类 item

package com.cxb;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.context.annotation.Bean;

import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;

@SpringBootApplication

public class item {

//读取配置文件信息

@Bean

public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() {

PropertySourcesPlaceholderConfigurer c = new PropertySourcesPlaceholderConfigurer();

c.setIgnoreUnresolvablePlaceholders(true);

return c;

}

public static void main(String[] args) {

SpringApplication.run(item.class,args);

}

}

数据库的部分应该就不用分享了吧,相信大家根据实体类能自己建出来,好啦,至此微信小程序的登录功能就完成啦,希望能对大家有所帮助。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java基础之StringBuffer详解
下一篇:Java基础之八大排序算法
相关文章

 发表评论

暂时没有评论,来抢沙发吧~