微信登录接口

说明

1、接口使用了swagger注解,可以删掉不用;
2、微信登录接口需部署到服务器才能测试访问,成功示例:
在这里插入图片描述

pom.xml

	<!--okhttp3-->
	<dependency>
		<groupId>com.squareup.okhttp3</groupId>
		<artifactId>okhttp</artifactId>
		<version>3.10.0</version>
	</dependency>

application.yml

	wechat:
  		openUrl: https://api.weixin.qq.com/sns/jscode2session
  		appId: ***
  		appSecret: ***
  		grantType: authorization_code

RestWechatController.java

package com.ruoyi.api.wechat;

import com.ruoyi.api.wechat.domain.WechatLoginVo;
import com.ruoyi.api.wechat.service.IWechatLoginService;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

/**
 * 微信授权登录
 * @author wangjiao
 * @version 1.0
 * @date 2020/4/23
 */
@Api(tags = "微信登录相关接口")
@RestController
@RequestMapping("/rest/wechat")
public class RestWechatController extends BaseController {
    @Autowired
    private IWechatLoginService service;

    @ApiOperation(value = "微信登录", notes = "登录实体Vo部分必填")
    @ApiImplicitParam(name = "wechatLoginVo", value = "登录实体Vo")
    @PostMapping("/login")
    @ResponseBody
    public AjaxResult login(@RequestBody WechatLoginVo entity) {
        return AjaxResult.success(service.login(entity));
    }

}

IWechatLoginService.java

package com.ruoyi.api.wechat.service;

import com.ruoyi.api.wechat.domain.WechatLoginVo;

/**
 * @author wangjiao
 * @version 1.0
 * @date 2020/4/23
 */
public interface IWechatLoginService {
    WechatLoginVo login(WechatLoginVo entity);
}

WechatLoginServiceImpl.java

	package com.ruoyi.api.wechat.service;

import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.ServiceException;
import com.ruoyi.admin.wechat.service.IEpWechatUserService;
import com.ruoyi.api.wechat.domain.EpWechatUser;
import com.ruoyi.api.wechat.domain.WechatLoginVo;
import com.ruoyi.api.wechat.util.WechatHttpUtils;
import com.ruoyi.api.wechat.util.WechatUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.Map;
import java.util.Objects;

/**
 * @author wangjiao
 * @version 1.0
 * @date 2020/4/23
 */
@Slf4j
@Service
public class WechatLoginServiceImpl implements IWechatLoginService {

    @Autowired
    private IEpWechatUserService service;

    @Value("${wechat.appId}")
    private String appId;

    @Value("${wechat.appSecret}")
    private String secret;

    @Value("${wechat.grantType}")
    private String grantType;

    @Value("${wechat.openUrl}")
    private String wechatOpenUrl;

    @Override
    public WechatLoginVo login(WechatLoginVo wechatLoginVo) {
        try {
            log.info("loginByCode进入=============" + wechatLoginVo.toString());
            WechatLoginVo returnVo = new WechatLoginVo();
            if (StringUtils.isBlank(wechatLoginVo.getCode())) {
                throw new RuntimeException("授权码不能为空");
            }
            Map<String, Object> wxResult = getOpenIdByHttpClient(wechatLoginVo.getCode());
            log.info(wxResult.toString());
            String sessionkey = "";
            if (wxResult.containsKey("session_key")) {
                sessionkey = wxResult.get("session_key").toString();
            }

            String openid = "";
            if (wxResult.containsKey("openid")) {
                openid = wxResult.get("openid").toString();
                log.info(openid);
                /**
                 * 如果已经注册过了 直接返回数据
                 */
                EpWechatUser epWechatUser = service.selectEntityByOpenId(openid);
                if (Objects.nonNull(epWechatUser)) {
                    BeanUtils.copyProperties(epWechatUser, returnVo);
                    return returnVo;
                }
            }
            if (StringUtils.isBlank(wechatLoginVo.getEncryptedData()) || StringUtils.isBlank(wechatLoginVo.getIv())) {
                throw new RuntimeException("加密的数据不能为空");
            }
            if (StringUtils.isBlank(sessionkey)) {
                throw new RuntimeException("授权信息有误");
            }
            JSONObject userInfo = WechatUtil.getUserInfo(wechatLoginVo.getEncryptedData(), sessionkey, wechatLoginVo.getIv());
            log.info(userInfo.toJSONString());
            returnVo = JSONObject.toJavaObject(userInfo, WechatLoginVo.class);
            //注册账号
            int result=insertWechatUser(returnVo);
            if(result>0){
                return returnVo;
            }
            throw new RuntimeException("注册账号失败");
        } catch (IOException e) {
            e.printStackTrace();
        }
        throw new RuntimeException("登录失败,服务器错误");
    }

    public Map<String, Object> getOpenIdByHttpClient(String code) throws IOException {
        WechatHttpUtils httpUtil = new WechatHttpUtils();
        String result = httpUtil.header("X-Requested-With", "XMLHttpRequest")
                .data("appid", appId)
                .data("secret", secret)
                .data("js_code", code)
                .data("grant_type", grantType)
                .url(wechatOpenUrl)
                .get();
        Map<String, Object> map = JSONObject.parseObject(result, Map.class);
        if (!map.containsKey("openid")) {
            throw new ServiceException("错误信息:" + map.get("errmsg"));
        }
        return map;
    }

    private int insertWechatUser(WechatLoginVo wechatLoginVo) {
        EpWechatUser entity = new EpWechatUser();
        BeanUtils.copyProperties(wechatLoginVo, entity);
        return service.insertEntity(entity);
    }
}

WechatUtil.java

	package com.ruoyi.api.wechat.util;

import com.alibaba.fastjson.JSONObject;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import java.security.Security;
import java.util.Arrays;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.AlgorithmParameters;

/**
 * @author wangjiao
 * @version 1.0
 * @date 2020/4/23
 */
public class WechatUtil {
    public static JSONObject getUserInfo(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 + (keyByte.length % base != 0 ? 1 : 0);
                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) {
            e.printStackTrace();
        }
        return null;
    }
}

WechatHttpUtils.java

	package com.ruoyi.api.wechat.util;

import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.apache.commons.lang.StringUtils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;

/**
 * @author wangjiao
 * @version 1.0
 * @date 2020/4/29
 */
@Slf4j
public class WechatHttpUtils {

    private Map<String, String> headers = new LinkedHashMap<>();
    private Map<String, String> queryParas = new LinkedHashMap<>();
    private String url = "";
    private Request.Builder requestBuilder = new Request.Builder();
    private OkHttpClient.Builder httpClient = new OkHttpClient().newBuilder().connectTimeout(10, TimeUnit.SECONDS).readTimeout(60, TimeUnit.SECONDS).writeTimeout(30, TimeUnit.SECONDS);

    public WechatHttpUtils header(String key, String value) {
        this.headers.put(key, value);
        return this;
    }

    public WechatHttpUtils data(String key, String value) {
        this.queryParas.put(key, value);
        return this;
    }

    public WechatHttpUtils url(String url) {
        this.url = url;
        return this;
    }

    /**
     * Send GET request
     *
     * @throws IOException
     */
    public String get() throws IOException {
        if (StringUtils.isEmpty(url)) {
            log.error("URL为空");
            return "";
        }

        requestBuilder.url(buildUrlWithQueryString(url, queryParas));
        for (Entry<String, String> entry : headers.entrySet()) {
            requestBuilder.addHeader(entry.getKey(), entry.getValue());
        }

        Request request = requestBuilder.build();
        Response response = httpClient.build().newCall(request).execute();

        if (!response.isSuccessful()) {
            throw new IOException("GET请求服务器端错误: " + response);
        }

        return response.body().string();
    }


    /**
     * Build queryString of the url
     */
    private static String buildUrlWithQueryString(String url, Map<String, String> queryParas) {
        if (queryParas == null || queryParas.isEmpty()) {
            return url;
        }

        StringBuffer sb = new StringBuffer(url);
        boolean isFirst;
        if (!url.contains("?")) {
            isFirst = true;
            sb.append("?");
        } else {
            isFirst = false;
        }

        for (Entry<String, String> entry : queryParas.entrySet()) {
            if (isFirst) {
                isFirst = false;
            } else {
                sb.append("&");
            }

            String key = entry.getKey();
            String value = entry.getValue();
            if (StringUtils.isEmpty(value)) {
                try {
                    value = URLEncoder.encode(value, "UTF-8");
                } catch (UnsupportedEncodingException e) {
                    throw new RuntimeException(e);
                }
            }
            sb.append(key).append("=").append(value);
        }
        return sb.toString();
    }

}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值