JAVA(SpringBoot)对接微信登录

目录

1 申请测试账号

1.1 登录测试平台

1.2 配置接口配置信息

​编辑

1.3 配置JS接口安全域名

1.4 配置网页授权获取用户基本信息

 2:接口代码

 2.1 微信登录流程

2.2 依赖导入:

2.2.1 工具类:

2.3 创建微信用户实体类

2.4 接口功能

3 测试



1 申请测试账号

1.1 登录测试平台

链接: 微信公众平台测试

1.2 配置接口配置信息

在这一步,需要拥有能接入公网的服务器,或者利用内网穿透将自己的接口暴漏给微信,让微信的回调能成功访问到我们的接口

在可以将我们的接口暴漏在公网的前提下,我们可以书写接口配置接口配置信息的URL:(注意:这里只是简单配置URL,未添加验证微信服务器流程,详细配置请参考:点击进入)

import javax.servlet.http.HttpServletRequest;

@RestController
@RequestMapping("/weChat")
public class WeChatController{

    @GetMapping("/verifyToken")
    public String verifyToken(HttpServletRequest request) {
        return request.getParameter("echostr");
    }

}

比如我们的服务器地址是 119.3.248.100 ,上述服务部署在了该服务器8080端口上,那么按照上述代码的路径,URL就可配置为:http://119.3.248.100:8080/weChat/verifyToken (有域名使用域名即可)

1.3 配置JS接口安全域名

在测试公众号中,可以使用 IP + 端口 的形式设置安全域名,这里的域名填写上述服务你所部署的服务器地址即可 

1.4 配置网页授权获取用户基本信息

 这里的授权回调页面域名和JS接口安全域名保持一致即可


 2:接口代码

 2.1 微信登录流程

微信客户端发送登录请求 -> 访问微信授权接口 -> 微信回调,j将授权code发送到我们的服务器 -> 通过code,appid,appsecret获取微信针对该用户的accsess_token,openid等信息-> 通过accsess_token,openid获取用户信息

2.2 依赖导入:

在下叙代码中使用到了hutool的工具类,swagger的工具类,通过maven的pom文件导入:(注:实体类使用了一些mybatis-plus的注解,如无用删除即可)

<!--        hutool工具依赖-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.10</version>
        </dependency>

     <!-- Swagger3 -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-boot-starter</artifactId>
            <version>3.0.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>3.0.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.github.xiaoymin/knife4j-spring-boot-starter -->
        <dependency>
        <groupId>com.github.xiaoymin</groupId>
        <artifactId>knife4j-spring-boot-starter</artifactId>
        <version>3.0.3</version>
        </dependency>

2.2.1 工具类:



import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSONObject;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Map;

/**
 * 微信登录工具类
 *
 * @author 
 * @date 2023/11/1 15:28
 */
public class WeiXinUtil {

    private static final String appId = "xxxx";
    private static final String appsecret = "xxxx";
    private static final String getCodeUrl = "https://open.weixin.qq.com/connect/oauth2/authorize";
    private static final String redirectUrl = "http://xxxxx/v1/login/getAccessToken";
    private static final String getAccessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token";
    private static final String refreshTokenUrl = "https://api.weixin.qq.com/sns/oauth2/refresh_token";
    private static final String getUserInfo = "https://api.weixin.qq.com/sns/userinfo";

    /**
     * 获取微信授权code
     * @param state 附加信息
     * @return
     */
    public static String getCode(String state) {
        try {
            StringBuffer url = new StringBuffer();
            url.append("redirect:")
                    .append(getCodeUrl)
                    .append("?appid=")
                    .append(appId)
                    .append("&redirect_uri=")
                    .append(URLEncoder.encode(redirectUrl, "UTF-8"))
                    .append("&response_type=code&scope=snsapi_userinfo&state=")
                    .append(state)
                    .append("#wechat_redirect");
            return url.toString();
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("URL格式化异常");
        }

    }

    /**
     * 获取微信AccessToken
     * @param code 用户code
     * @return
     */
    public static Map<?, ?> getAccessToken(String code) {
        StringBuffer url = new StringBuffer();
        url.append(getAccessTokenUrl)
                .append("?appid=")
                .append(appId)
                .append("&secret=")
                .append(appsecret)
                .append("&code=")
                .append(code)
                .append("&grant_type=authorization_code");
        String rs = HttpUtil.get(url.toString());
        Map map = JSONObject.parseObject(rs, Map.class);
        if (null == map.get("errcode")) {
            return map;
        } else {
            throw new RuntimeException("获取access_token出错");
        }
    }

    /**
     * 刷新AccessToken
     * @param refreshToken
     * @return
     */
    public static Map refreshToken(String refreshToken) {
        StringBuffer url = new StringBuffer();
        url.append(refreshTokenUrl)
                .append("?appid=")
                .append(appId)
                .append("&grant_type=refresh_token&refresh_token=")
                .append(refreshToken);
        String rs = HttpUtil.get(url.toString());
        Map map = JSONObject.parseObject(rs, Map.class);
        if (null == map.get("errcode")) {
            return map;
        } else {
            throw new RuntimeException("刷新access_token出错");
        }
    }

    /**
     * 获取用户信息
     * @param accessToken
     * @param openid
     * @return
     */
    public static String getUserInfo(String accessToken, String openid) {
        StringBuffer url = new StringBuffer();
        url.append(getUserInfo)
                .append("?access_token=")
                .append(accessToken)
                .append("&openid=")
                .append(openid)
                .append("&lang=zh_CN");
        String rs = HttpUtil.get(url.toString());
        return rs;
    }
}

2.3 创建微信用户实体类


import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

import java.io.Serializable;
import java.util.Date;

/**
 *
 * 微信用户信息
 * @author 
 * @date 2023/11/1 16:20
 */
@TableName(value = "wx_user")
@Data
public class WXUser implements Serializable {
    private static final long serialVersionUID = -40356785423868312L;

    @TableId(type = IdType.AUTO)
    private Long id;
    /**
     * 系统用户id
     */
    private Long userId;
    /**
     * 用户的唯一标识
     */
    private String openid;
    /**
     * access_token
     */
    private String accessToken;

    /**
     * refresh_token
     */
    private String refreshToken;
    /**
     * 用户昵称
     */
    private String nickname;
    /**
     * 性别(0未知,1男性,2女性)
     */
    private String sex;
    /**
     * 用户个人资料填写的省份
     */
    private String province;
    /**
     * 普通用户个人资料填写的城市
     */
    private String city;
    /**
     * 国家,如中国为CN
     */
    private String country;
    /**
     * 用户头像
     */
    private String headimgurl;
    /**
     * 用户特权信息,json 数组
     */
    private String privilege;
    /**
     *
     */
    private String unionid;

    private Date createTime;

    private Date updateTime;

    private Long createBy;

    private Long updateBy;
}

2.4 接口功能

import javax.servlet.http.HttpServletRequest;

@Controller
@RequestMapping("/weChat")
public class WeChatController{

    @ResponseBody
    @GetMapping("/verifyToken")
    @ApiOperation("微信Token验证")
    public String verifyToken(HttpServletRequest request) {
        return request.getParameter("echostr");
    }

    @GetMapping("/getCode")
    @ApiOperation("获取微信code")
    public String weiXinLogin(@RequestParam(defaultValue = "123") String state) {
        return WeiXinUtil.getCode(state);
    }

    @ResponseBody
    @GetMapping("/getAccessToken")
    @ApiOperation("获取token")
    public String getAccessToken(@RequestParam String code) {
        Map result = WeiXinUtil.getAccessToken(code);
        String accessToken = result.get("access_token").toString();
        String refreshToken = result.get("refresh_token").toString();
        String openid = result.get("openid").toString();
        WXUser wxUser = new WXUser();
        wxUser.setAccessToken(accessToken);
        wxUser.setRefreshToken(refreshToken);
        wxUser.setCreateTime(new Date());
        wxUser.setUserId(1L);
        wxUser.setOpenid(openid);
        wxUserService.save(wxUser);
        return "<h1>看样子成功了,没你事了退下吧</h1>";
    }

    @ResponseBody
    @GetMapping("/refreshToken")
    @ApiOperation("刷新token")
    public R refreshToken() {
        Long userId = 1L;
        WXUser wxUser = wxUserService.getOne(new LambdaUpdateWrapper<WXUser>().eq(WXUser::getUserId, userId));
        Map result = WeiXinUtil.refreshToken(wxUser.getRefreshToken());
        String accessToken = result.get("access_token").toString();
        String refreshToken = result.get("refresh_token").toString();
        WXUser wxUserUpdate = new WXUser();
        wxUserUpdate.setId(wxUser.getId());
        wxUserUpdate.setAccessToken(accessToken);
        wxUserUpdate.setRefreshToken(refreshToken);
        wxUserUpdate.setUpdateTime(new Date());
        wxUserService.updateById(wxUserUpdate);
        return R.data(accessToken);
    }

    @ResponseBody
    @GetMapping("/getUserInfo")
    @ApiOperation("获取用户信息")
    public R getUserInfo() {
        Long userId = 1L;
        WXUser wxUser = wxUserService.getOne(new LambdaUpdateWrapper<WXUser>().eq(WXUser::getUserId, userId));
        String accessToken = wxUser.getAccessToken();
        String openid = wxUser.getOpenid();
        String userInfoJsom = WeiXinUtil.getUserInfo(accessToken, openid);
        WXUser userInfo = JSONObject.parseObject(userInfoJsom, WXUser.class);
        userInfo.setId(wxUser.getId());
        userInfo.setUpdateTime(new Date());
        wxUserService.updateById(userInfo);
        return R.data(userInfo);
    }

}

3 测试

微信扫码关注测试公众号

生成一个二维码调用获取code的接口,百度搜索  将获取code的URL路径填入码,手机微信扫码即可 : 草料文本二维码生成器,微信通过此入口即可访问获取code的页面, 注意:一定要使用手机微信客户端扫码二维码

流程:

获取code中的 redirect_uri 参数可以配置为我们的微信登录接口,这里为了演示功能,配置成了获取access_token 的接口

1. 通过获取code的接口,微信会通过我们配置的redirect_uri参数回调我们的接口,并会携带上code参数,同时注意此接口不要添加@ResponseBody 的注解

2. 微信回调获取access_token的接口,我们可以获取到access_token,refresh_token,openid这三个重要参数,这也是获取用户个人信息的关键

3. 刷新access_token的步骤可省略,有需要时可以调用此功能

4. 获取用户信息,这里获取用户信息的前提是我们在获取code的接口中,参数中的授权范围参数写为snsapi_userinfo 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值