java对接微信小程序(登录&获取用户信息)

这篇具有很好参考价值的文章主要介绍了java对接微信小程序(登录&获取用户信息)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

需求说明:

用户通过小程序登录,进入到平台系统,进行各功能操作;

解决方案:

首先通过对接小程序,用户通过小程序登录及授权获取用户信息,后端调用接口获取微信用户信息,进行保存到数据库,然后返回token给前端(实际在这里相当于用户的一个注册及登录),前端使用该token访问所有接口;

相关代码:
首先我们需要用到 http工具类 方便后续的接口调用:

import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
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;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class HttpClientUtils {
  
    final static int TIMEOUT = 1000;
 
    final static int TIMEOUT_MSEC = 5 * 1000;   
  
    public static String doPost(String url, Map<String, String> paramMap) throws IOException {
        // 创建Httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String resultString = "";
 
        try {
            // 创建Http Post请求
            HttpPost httpPost = new HttpPost(url);
 
            // 创建参数列表
            if (paramMap != null) {
                List<NameValuePair> paramList = new ArrayList<>();
                for (Map.Entry<String, String> param : paramMap.entrySet()) {
                    paramList.add(new BasicNameValuePair(param.getKey(), param.getValue()));
                }
                // 模拟表单
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList);
                httpPost.setEntity(entity);
            }
 
            httpPost.setConfig(builderRequestConfig());
 
            // 执行http请求
            response = httpClient.execute(httpPost);
 
            resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
        } catch (Exception e) {
            throw e;
        } finally {
            try {
                response.close();
            } catch (IOException e) {
                throw e;
            }
        }
 
        return resultString;
    }
  
    private static RequestConfig builderRequestConfig() {
        return RequestConfig.custom()
                .setConnectTimeout(TIMEOUT_MSEC)
                .setConnectionRequestTimeout(TIMEOUT_MSEC)
                .setSocketTimeout(TIMEOUT_MSEC).build();
    }
}
小程序用户表
CREATE TABLE `wechat_user` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `nickname` varchar(100) DEFAULT NULL COMMENT '用户昵称',
  `avatar_url` varchar(500) DEFAULT NULL COMMENT '用户头像',
  `gender` int(11) DEFAULT NULL COMMENT '性别  0-未知、1-男性、2-女性',
  `country` varchar(100) DEFAULT NULL COMMENT '所在国家',
  `province` varchar(100) DEFAULT NULL COMMENT '省份',
  `city` varchar(100) DEFAULT NULL COMMENT '城市',
  `mobile` varchar(100) DEFAULT NULL COMMENT '手机号码',
  `open_id` varchar(100) NOT NULL COMMENT '小程序openId',
  `union_id` varchar(100) DEFAULT '' COMMENT '小程序unionId',
  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '插入时间',
  `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`),
  KEY `idx_open_id` (`open_id`),
  KEY `idx_union_id` (`union_id`),
  KEY `idx_mobile` (`mobile`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC COMMENT='小程序用户表';

dto

import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import javax.validation.constraints.NotNull;

@Data
public class WechatLoginRequest {

	//登录时获取的 code,可通过wx.login获取
    @NotNull(message = "code不能为空")
    @ApiModelProperty(value = "微信code", required = true)
    private String code;
	
	//这个入参其实里面包含了用户的信息 下面的impl层 就是解析这个json获取用户信息
    @ApiModelProperty(value = "用户非敏感字段")
    private String rawData;

    @ApiModelProperty(value = "签名")
    private String signature;

    @ApiModelProperty(value = "用户敏感字段")
    private String encryptedData;

    @ApiModelProperty(value = "解密向量")
    private String iv;
}

主要代码:

controller


import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
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 javax.annotation.Resource;

@RestController
@RequestMapping("/wechat")
@Api(tags = {"微信小程序"}, value = "/wechat")
@Slf4j
public class LoginController {
    @Resource
    private WechatService wechatService;
    
    @ApiOperation(value = "登入接口", httpMethod = "POST")
    @PostMapping("/login")
    public ResponseResult login(@Validated @RequestBody WechatLoginRequest loginRequest) throws Exception {
        return wechatService.getUserInfoMap(loginRequest);
    }
}

mapper

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.mmc.aircraftsystemserver.api.wechet.pojo.WechatUser;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface WechatMapper extends BaseMapper<WechatUser> {

}

impl

package com.mmc.aircraftsystemserver.api.wechet.service.impl;

import cn.hutool.core.codec.Base64;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.AlgorithmParameters;
import java.security.Security;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class WechatServiceImpl extends ServiceImpl<WechatMapper, WechatUser> implements WechatService {
	
	//小程序 appId
    @Value("${wechat.appid}")
    private String APPID;
    
    //小程序 appSecret
    @Value("${wechat.secret}")
    private String SECRET;
    
    //${wechat.grantType} = authorization_code
    @Value("${wechat.grantType}")
    private String GRANT_TYPE;
    
    // ${wechat.url} = https://api.weixin.qq.com/sns/jscode2session
    @Value("${wechat.url}")
    private String REQUEST_URL;


    public ResponseResult getUserInfoMap(WechatLoginRequest loginRequest) throws Exception {
        JSONObject sessionKeyOpenId = getSessionKeyOrOpenId(loginRequest.getCode());
        // 获取openId && sessionKey
        String openId = sessionKeyOpenId.getString("openid");
        String sessionKey = sessionKeyOpenId.getString("session_key");

        //校验签名 小程序发送的签名signature与服务器端生成的签名signature2 = sha1(rawData + sessionKey)
        String signature2 = DigestUtils.sha1Hex(loginRequest.getRawData() + sessionKey);
        if (!loginRequest.getSignature().equals(signature2)) {
            return ResponseResult.errorResult(HttpCodeEnum.FAIL, "签名校验失败");
        }
        
        WechatUser insertOrUpdateDO = buildWechatUserAuthInfoDO(loginRequest, sessionKey, openId);
 
        // 根据code保存openId和sessionKey
        JSONObject sessionObj = new JSONObject();
        sessionObj.put("openId", openId);
        sessionObj.put("sessionKey", sessionKey);

        // 根据openid查询用户
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("open_id",openId);
        WechatUser user = getOne(wrapper);
        if (user == null) {
            // 用户不存在,insert用户
            save(insertOrUpdateDO);
        } else {
            // 已存在,更新用户的信息
            UpdateWrapper<WechatUser> updateWrapper = new UpdateWrapper();
            updateWrapper.eq("openId",openId)
                    .set("nickname",insertOrUpdateDO.getNickname())
                    .set("avatar_url",insertOrUpdateDO.getAvatarUrl())
                    .set("gender",insertOrUpdateDO.getGender())
                    .set("country",insertOrUpdateDO.getCountry())
                    .set("province",insertOrUpdateDO.getProvince())
                    .set("city",insertOrUpdateDO.getCity())
                    .set("mobile",insertOrUpdateDO.getMobile());
           update(updateWrapper);
        }
        ResponseResult token = createToken(insertOrUpdateDO);
        return ResponseResult.okResult(token);
    }

	//调用接口
    private JSONObject getSessionKeyOrOpenId(String code) throws Exception {
        Map<String, String> requestUrlParam = new HashMap<>();
        requestUrlParam.put("appid", APPID);
        requestUrlParam.put("secret", SECRET);
        requestUrlParam.put("js_code", code);
        requestUrlParam.put("grant_type", GRANT_TYPE);
 
        // 发送post请求读取调用微信接口获取openid用户唯一标识
        String result = HttpClientUtils.doPost(REQUEST_URL, requestUrlParam);
        return JSON.parseObject(result);
    }
  
    private WechatUser buildWechatUserAuthInfoDO(WechatLoginRequest loginRequest, String sessionKey, String openId){
        WechatUser wechatUserDO = new WechatUser();
        wechatUserDO.setOpenId(openId);
 
        if (loginRequest.getRawData() != null) {
            RawDataDO rawDataDO = JSON.parseObject(loginRequest.getRawData(), RawDataDO.class);
            wechatUserDO.setNickname(rawDataDO.getNickName());
            wechatUserDO.setAvatarUrl(rawDataDO.getAvatarUrl());
            wechatUserDO.setGender(rawDataDO.getGender());
            wechatUserDO.setCity(rawDataDO.getCity());
            wechatUserDO.setCountry(rawDataDO.getCountry());
            wechatUserDO.setProvince(rawDataDO.getProvince());
        }
 
        // 解密加密信息,获取unionID
        if (loginRequest.getEncryptedData() != null){
            JSONObject encryptedData = getEncryptedData(loginRequest.getEncryptedData(), sessionKey, loginRequest.getIv());
            if (encryptedData != null){
                String unionId = encryptedData.getString("unionId");
                wechatUserDO.setUnionId(unionId);
            }
        }
 
        return wechatUserDO;
    }
  
    private JSONObject getEncryptedData(String encryptedData, String sessionkey, String iv) {
        // 被加密的数据
        byte[] dataByte = Base64.decode(encryptedData);
        // 加密秘钥
        byte[] keyByte = Base64.decode(sessionkey);
        // 偏移量
        byte[] ivByte = Base64.decode(iv);
        try {
            // 如果密钥不足16位,那么就补足.这个if中的内容很重要
            int base = 16;
            if (keyByte.length % base != 0) {
                int groups = keyByte.length / base + 1;
                byte[] temp = new byte[groups * base];
                Arrays.fill(temp, (byte) 0);
                System.arraycopy(keyByte, 0, temp, 0, keyByte.length);
                keyByte = temp;
            }
            // 初始化
            Security.addProvider(new BouncyCastleProvider());
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");
            SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");
            AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");
            parameters.init(new IvParameterSpec(ivByte));
            cipher.init(Cipher.DECRYPT_MODE, spec, parameters);// 初始化
            byte[] resultByte = cipher.doFinal(dataByte);
            if (null != resultByte && resultByte.length > 0) {
                String result = new String(resultByte, "UTF-8");
                return JSONObject.parseObject(result);
            }
        } catch (Exception e) {
            log.error("解密加密信息报错", e.getMessage());
        }
        return null;
    }

	//生成token 这里可以忽略 根据自己当前业务系统选取生成方式
    public ResponseResult createToken(WechatUser wechatUser) {
        String openid = wechatUser.getOpenId();
        String token = MD5Util.getMD5Str(openid + System.currentTimeMillis());

        String flyingSessionId = MD5Util.getMD5Str("HAHA" + wechatUser.getOpenId());
        wechatUser.getStringRedisTemplate().opsForValue().set(token, wechatUser.getNickname());

        //外部登录生成token
        String key = token + flyingSessionId;
        Map<String, String> redisData = new HashMap<>();
        redisData.put("HAHA-TOKEN", token);
        redisData.put("HAHA-SESSIONID", flyingSessionId);
        redisData.put("uid", wechatUser.getId() + "");
        redisData.put("openid", wechatUser.getOpenId());
        redisData.put("nickname", wechatUser.getNickname());
        wechatUser.getStringRedisTemplate().opsForHash().putAll(key, redisData);
        wechatUser.getStringRedisTemplate().expire(key, 86400, TimeUnit.SECONDS);
        return ResponseResult.okResult(redisData);
    }

}

注意:

微信小程序更新后:
java 微信小程序获取用户信息,java,微信小程序,前端
#### 前端调用接口 参数一次性给齐 这样就可以一次调用 获取所有;文章来源地址https://www.toymoban.com/news/detail-555058.html

到了这里,关于java对接微信小程序(登录&获取用户信息)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • java实现小程序获取微信登录,用户信息,手机号,头像

    在上面的代码中,首先定义了应用的AppID和AppSecret。然后,实现了获取微信用户access_token的方法getAccessToken()和获取微信用户信息的方法getUserInfo()。其中,getAccessToken()方法需要传入微信小程序登录时获取的code,会返回一个包含access_token和openid的Map;getUserInfo()方法需要传入用户

    2024年02月12日
    浏览(11)
  • 微信小程序实现登录授权,并将获取到的用户授权信息存储到数据库中

    微信小程序实现登录授权,并将获取到的用户授权信息存储到数据库中

    官方开发文档 注意:在实现授权登录时,不要使用测试号进行 wx.getUserProfile使用文档 config文件代码如下 路由模块 主要代码(如果不想多个文件,可以将wxuserHandle.wxuser这个位置内容替换为exports.wxuser的内容) 注意: 在返回token的字符串拼接时,Bearer 后面必须有一个空格 数据

    2024年02月10日
    浏览(20)
  • (详细版)java实现小程序获取微信登录,用户信息,手机号,头像

    ps:springboot结合mybatisPlus、mysql实现,简单易懂,一件粘贴使用,详细往下看↓          1.注册微信开发平台账号,并创建小程序,获取小程序的AppID和AppSecret。 2.在小程序中引导用户点击按钮触发微信登录,获取到code。 3.将code发送到后端,后端通过code获取用户的openid和

    2024年02月01日
    浏览(10)
  • 基于uniapp+java实现微信小程序无感登录,授权手机号登录,获取昵称头像,获取定位信息

    基于uniapp+java实现微信小程序无感登录,授权手机号登录,获取昵称头像,获取定位信息

    使用uniapp开发微信小程序,避免不了微信登录。但自动微信2022年升级了api版本后,不再允许返回昵称和头像信息,所以才出现无感登录或授权手机号登录。实现方式大同小异。 java后端所需maven 前端实现代码: 由于使用uni.login并不需要用户授权,所以能做到无感登录。 后端

    2024年02月16日
    浏览(31)
  • uniapp(vue3) - 详解微信小程序平台用户授权登录全流程,uniapp v3版本中小程序端开发下用户点击登录后获取手机号/昵称/性别/头像等信息完成登录(提供完整示例代码,一键复制开箱即用)

    uniapp(vue3) - 详解微信小程序平台用户授权登录全流程,uniapp v3版本中小程序端开发下用户点击登录后获取手机号/昵称/性别/头像等信息完成登录(提供完整示例代码,一键复制开箱即用)

    在uniapp(v3)微信小程序端开发中,超详细实现用户授权登录完整功能源码,用户授权后获取手机号/昵称/头像/性别等,提供完整思路流程及逻辑讲解。 你也可以直接复制粘贴,然后改下参数放到你的项目中去就行。 做功能之前,先

    2024年02月05日
    浏览(20)
  • 微信小程序获取用户信息

    要在微信小程序中获取用户信息,你可以按照以下步骤进行操作: 1. 在小程序的app.json文件中添加\\\"scope.userinfo\\\"权限,例如: ``` \\\"permission\\\": {   \\\"scope.userinfo\\\": {     \\\"desc\\\": \\\"你的个人信息\\\"   } } ``` 2. 在小程序的某个页面中,使用wx.login方法获取用户登录凭证code,例如: ``` wx.log

    2024年02月10日
    浏览(13)
  • 微信小程序获取用户信息流程

    要在微信小程序中获取用户信息,通常需要经过以下流程: 此外,还需要在小程序的 app.json 文件中配置 scope.userInfo 以确保可以请求用户信息授权。例如: 需要注意的是,从微信 7.0.0 开始,用户信息授权不再是全量授权,而是分为两部分:基本信息和用户敏感信息。基本信

    2024年02月05日
    浏览(9)
  • 微信小程序—获取用户位置信息

    微信小程序—获取用户位置信息

    代码: 结果示例: 接下来我们需要经度(longitude)和纬度(latitude)两个属性

    2024年02月08日
    浏览(12)
  • 微信小程序获取用户信息nickname为“微信用户”

    微信小程序获取用户信息nickname为“微信用户”

    最近两天小程序用户登录获取到的用户微信名称都变成了\\\"微信用户\\\",在网上找到的问题原因是getUserProfile API被收回微信社区 头像昵称填写能力可以获取用户头像和昵称直接上代码,如果有更好的方案请留言!!!!!!!!

    2024年02月12日
    浏览(9)
  • 微信小程序-获取用户信息【梳理历史】

    微信小程序-获取用户信息【梳理历史】

    有一个迭代的过程,时间很近 大概分为4个内容 1.2021年4月15日  简述:回收了一个接口,新增了一个接口 小程序登录、用户信息相关接口调整说明 | 微信开放社区 (qq.com) 通过wx.login接口获取的登录凭证可直接换取unionID 回收wx.getUserInfo接口可获取用户个人信息能力 新增getUse

    2024年02月11日
    浏览(11)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包