uniapp_微信小程序_登录demo_springboot接口实现

微信小程序授权流程+说明

授权流程说明官方链接
授权流程图
在这里插入图片描述

我的理解(一得之见,如有错误,欢迎指出哈)

1.前端获取小程序的code,调用后端接口
2.后端获取code,结合写在配置文件里的appid和secret,用GET请求‘(https://api.weixin.qq.com/sns/jscode2session)’,获取sesson_key和openid;
3.后端用加密算法把返回的sesson_key和openid加密并写入httpsesson或者redis中,配置这个值的有效时间,返回保存体的id;
4.前端获取这个值保存,后续接口都增加这个ID,后端校验是否失效,失效的话就重新登录。

uniapp前端页面

代码结构

登录界面预览

在这里插入图片描述

登录界面前端代码

<template>
	<view>
		<view>
			<view>
				<view class="header">
					<image src="/static/login-wx.jpg"></image>
				</view>
				<view class="content">
					<view>申请获取以下权限</view>
					<text>获得你的公开信息(昵称,头像、地区等)</text>
				</view>
				<button class="bottom" type="primary" :disabled="userInfoDisabled" @click="wxGetUserInfo">授权登录</button>
			</view>
		</view> 
	</view>
</template>
 
<script>  

export default { 
		data(){
			 return {
				 userInfoDisabled: false
			 }
		 } ,
		onLoad() {
			
		},
		methods :{
		 wxGetUserInfo(){ 
			 console.log("点击测试!")
			 uni.login({ 
			 	"provider": "weixin",
			 	"onlyAuthorize": true, // 微信登录仅请求授权认证
			 	success: function(event){
					console.log(event)
					uni.showLoading({
					                        title: '授权中...'
					                    })
									uni.getUserInfo({
														  provider: 'weixin',
														  success: function (infoRes) {
															console.log(infoRes.userInfo)
															console.log('用户昵称为:' + infoRes.userInfo );
									 }})
										
										 
					uni.request({
					      url:'http://localhost:8090/user/getWxInfoTest',        //请求的地址,类型为String
					      data:event.code,      //要求为Object或String类型的参数,发送到服务器的数据。如果已经不是字符串,将自动转换为字符串格式。get请求中将附加在url后
					      method:'post',    //get、post、delete 
					      success:res=>{
							  console.log(res.data)
							  uni.setStorage({
							    key: 'token',
							    data: 'res.data',
							    success: function () {
							      uni.showToast({
							      			title: '授权成功',
							      			icon: 'success',
							      			duration: 1000,
							      			})
										uni.switchTab({
													url: '../index/index'
												});

							    }
							  })
						  } }) 
					}
				})
		    }
		 }
	 }
  
</script>
<style lang="scss" scoped>
	.header {
		margin: 160rpx 0 60rpx 50rpx;
		text-align: center;
		width: 650rpx;
 
		image {
			width: 180rpx;
			height: 180rpx;
		}
	}
 
	.content {
		margin-bottom: 68rpx;
		text-align: center;
 
		text {
			display: block;
			color: #9d9d9d;
			margin-top: 20rpx;
		}
	}
 
	.bottom {
		border-radius: 80rpx;
		margin: 70rpx 50rpx;
		font-size: 35rpx; 
	}
	.login-wrapper{
		height: 100%;
		position: relative;
		.login-bottom{
			position: absolute;
			bottom: 0;
			left: 0;
			width: 100%;
			height: 133rpx;
			background-color: #fff;
			button{
				position: absolute;
				top: 50%;
				left: 50%;
				background-color: #CA2915;
				transform: translate(-50%, -50%);
				border-radius: 30px;
				width: 435rpx;
				height: 68rpx;
				line-height: 68rpx;
			}
		}
	}
</style>

后端springboot配置及接口

后端代码结构

在这里插入图片描述

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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>wx</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>wx</name>
    <description>wx</description>
    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.6.13</spring-boot.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.14</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.28</version>
        </dependency>

        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.10</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.2</version>
        </dependency>

        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
                <configuration>
                    <mainClass>com.example.wx.WxApplication</mainClass>
                    <skip>true</skip>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

配置文件 application.properties

#开启sesson缓存
spring.session.store-type=none
#设置缓存有效时间5分钟
server.servlet.session.timeout=5m
[微信官方平台扫码登录获取](https://mp.weixin.qq.com/)
wx.open.app_id=wx7941efe26a50548c
wx.open.secret=1063068c30ab233e160eeea31af17983
wx.open.token_url=https://api.weixin.qq.com/sns/jscode2session?

httpUtils.java

package com.example.wx.utils;

import lombok.extern.slf4j.Slf4j;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

@Slf4j
public class httpUtils {
    public static String getRequest(String httpurl) {
        log.info("完整的请求是{}", httpurl);
        HttpURLConnection connection = null;
        InputStream is = null;
        BufferedReader br = null;
        String result = null;// 返回结果字符串
        try {
            // 创建远程url连接对象
            URL url = new URL(httpurl);
            // 通过远程url连接对象打开一个连接,强转成httpURLConnection类
            connection = (HttpURLConnection) url.openConnection();
            // 设置连接方式:get
            connection.setRequestMethod("GET");
            // 设置连接主机服务器的超时时间:15000毫秒
            connection.setConnectTimeout(15000);
            // 设置读取远程返回的数据时间:60000毫秒
            connection.setReadTimeout(60000);
            // 发送请求
            connection.connect();
            // 通过connection连接,获取输入流
            if (connection.getResponseCode() == 200) {
                is = connection.getInputStream();
                // 封装输入流is,并指定字符集
                br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
                // 存放数据
                StringBuffer sbf = new StringBuffer();
                String temp = null;
                while ((temp = br.readLine()) != null) {
                    sbf.append(temp);
                    sbf.append("\r\n");
                }
                result = sbf.toString();
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            if (null != br) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != is) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            connection.disconnect();// 关闭远程连接
        }

        return result;
    }
}

MD5Util.java

package com.example.wx.utils;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * MD5加密解密工具类
 * @author admin
 *
 */
public class MD5Util {

    /**
     * 使用 MD5算法加密生成32位md5码
     * @param str
     * @return
     */
    public static String string2MD5(String str) {
        byte[] secretBytes = null;
        try {
            secretBytes = MessageDigest.getInstance("md5").digest(
                    str.getBytes());
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("没有md5这个算法!");
        }
        String md5code = new BigInteger(1, secretBytes).toString(16);// 16进制数字
        // 如果生成数字未满32位,需要前面补0
        for (int i = 0; i < 32 - md5code.length(); i++) {
            md5code = "0" + md5code;
        }
        return md5code;
    }

    /**
     * 	可逆的加密解密算法,执行一次加密,两次解密
     * @param str
     * @return
     */
    public static String convertMD5(String str){

        char[] a = str.toCharArray();
        for (int i = 0; i < a.length; i++){
            a[i] = (char) (a[i] ^ 't');
        }
        String s = new String(a);
        return s;

    }

}

SessionUtil.java

package com.example.wx.utils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

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

@Component
public class SessionUtil {
    @Autowired
    private HttpServletRequest request;

    public   String saveToSession(String key, Object value) {
        HttpSession session = request.getSession();
        session.setAttribute(key, value);
        return session.getId();
    }
}

WechatTools.java

package com.example.wx.utils;

import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;


public class WechatTools {

    public static String getOpenid(String code,String appid,String secret,String token_url) {
        StringBuilder data=new StringBuilder();
        data.append("appid="+ appid+"&");
        data.append("secret="+  secret+"&");
        data.append("js_code="+ code+"&");
        data.append("grant_type="+ "authorization_code");

        String response = httpUtils.getRequest(token_url + data);
        JSONObject jo= JSONObject.parseObject(response);
        jo.get("session_key");
        jo.get("openid");

        return response;
    }
}

UserController.java

package com.example.wx.controller;


import com.example.wx.utils.MD5Util;
import com.example.wx.utils.SessionUtil;
import com.example.wx.utils.WechatTools;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
    @Value("${wx.open.app_id}")
    private  String appid;
    @Value("${wx.open.secret}")
    private  String secret;
    @Value("${wx.open.token_url}")
    private  String token_url;
    @Autowired
    SessionUtil sessionUtil;

    /**
     * 微信小程序的登陆,如果有账号,则返回登陆成功,如果没有则返回(首次用户,需要认证)
     * @return
     */
    @PostMapping("/getWxInfoTest")
    public String getWxInfoTest(@RequestBody String obj) {
        log.info("传入的参数{}", obj);
        String finalStr=  WechatTools.getOpenid(obj,appid,secret,token_url);
        String md5= MD5Util.convertMD5(MD5Util.string2MD5(finalStr));
        String sessonId= sessionUtil.saveToSession(md5,finalStr);
        log.info("微信的返回值{}", finalStr);
        log.info("后端接口返回的seasonID:{}", finalStr);
        return sessonId;
    }
}

运行截图

在这里插入图片描述

运行结果

2023-12-07 18:53:00.653  INFO 21354 --- [nio-8090-exec-1] c.example.wx.controller.UserController   : 传入的参数0b1EO6ml20sGwc4F5kol2EQVG04EO6mp
2023-12-07 18:53:00.653  INFO 21354 --- [nio-8090-exec-1] com.example.wx.utils.httpUtils           : 完整的请求是https://api.weixin.qq.com/sns/jscode2session?appid=wx7941efe26a50548c&secret=1063068c30ab233e160eeea31af17983&js_code=0b1EO6ml20sGwc4F5kol2EQVG04EO6mp&grant_type=authorization_code
2023-12-07 18:53:01.081  INFO 21354 --- [nio-8090-exec-1] c.example.wx.controller.UserController   : 微信的返回值{"session_key":"rmFq7DZCy27OrztZLMNucg==","openid":"o4eNX0ikqYyiQAXSSBSMYMrPgN6E"}
2023-12-07 18:53:01.081  INFO 21354 --- [nio-8090-exec-1] c.example.wx.controller.UserController   : 后端接口返回的seasonID:{"session_key":"rmFq7DZCy27OrztZLMNucg==","openid":"o4eNX0ikqYyiQAXSSBSMYMrPgN6E"}
UniApp 是一个基于 Vue.js 的跨平台框架,可以同时构建 Web、H5、小程序等应用。在 UniApp实现微信小程序的授权登录,你需要遵循以下步骤: 1. **引入依赖**: 首先,在项目中安装微信小程序的 SDK: ```bash npm install uni-app-plus wx-login ``` 2. **配置权限管理**: 在 `uni.json` 文件中添加微信小程序的相关配置: ```json "framework": { "plus": { "login": { "enable": true, "scope": ["snsapi_userinfo"] } } } ``` 这里 `"scope"` 属性指定了需要获取用户信息的权限级别。 3. **注册登录按钮并处理逻辑**: 在页面模板中,添加微信登录的按钮,绑定到登录事件处理器: ```html <button bindtap="handleWechatLogin">微信登录</button> ``` 然后在对应的 JavaScript 中编写登录逻辑: ```javascript async handleWechatLogin() { try { const loginRes = await plus.login(); if (loginRes.code) { // 调用微信接口换取用户信息 const userInfo = await plus.oauth2.getUserInfo(loginRes.code); console.log('用户信息:', userInfo); // 存储或验证用户身份 } else { console.error('登录失败', loginRes); } } catch (error) { console.error('登录错误', error); } } ``` 4. **处理授权回调**: 微信服务器会将授权结果发送到你配置的回调地址,记得在后端设置相应的接收和处理逻辑。 注意,微信官方的登录流程是异步的,所以在处理登录请求时需要等待回调。此外,还要确保遵循微信小程序的隐私政策和用户协议。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值