步骤分析:
- 小程序端,调用wx.login()获取code,就是授权码。
- 小程序端,调用wx.request()发送请求并携带code,请求开发者服务器(自己编写的后端服务)。
- 开发者服务端,通过HttpClient向微信接口服务发送请求,并携带appId+appsecret+code三个参数。
- 开发者服务端,接收微信接口服务返回的数据,session_key+opendId等。opendId是微信用户的唯一标识。
- 开发者服务端,自定义登录态,生成令牌(token)和openid等数据返回给小程序端,方便后绪请求身份校验。
- 小程序端,收到自定义登录态,存储storage。
- 小程序端,后绪通过wx.request()发起业务请求时,携带token。
- 开发者服务端,收到请求后,通过携带的token,解析当前登录用户的id。
- 开发者服务端,身份校验通过后,继续相关的业务逻辑处理,最终返回业务数据。
具体代码步骤如下:
public class UserServiceImpl implements UserService {
// 微信服务接口地址
public static final String WX_LOGIN = "https://api.weixin.qq.com/sns/jscode2session";
@Autowired
private WeChatProperties weChatProperties;
@Autowired
private UserMapper userMapper;
/**
* 微信登录
*
* @param userLoginDTO
* @return com.sky.entity.User
* @author inbreak
* @create 2024/8/24
**/
/*
* 传统的用户名密码登录:查询用户表,检测用户名和密码是否正确
* 微信登录:由于是微信用户
* 1、调用微信服务器接口
* 2、获取当前用户的openid
* 3、判断当前用户的openid是否正确获取(若为空,则抛出业务异常)
* 4、判断当前用户是否为新用户(第一次使用该程序,若为新,则存入用户表,自动完成注册)
* 5、返回这个用户对象
*
* */
@Override
public User wxLogin(UserLoginDTO userLoginDTO) {
String openid = getOpenid(userLoginDTO.getCode());
// 判断openid是否为空,如果为空表示登录失败,抛出业务异常
if(null == openid){
throw new LoginFailedException(MessageConstant.LOGIN_FAILED);
}
// 判断当前用户是否为新用户
User user = userMapper.getByOpenid(openid);
// 如果是新用户,自动完成注册
if(null == user){
user = User.builder()
.openid(openid)
.createTime(LocalDateTime.now())
.build();
userMapper.insert(user);
}
// 返回这个用户对象
return user;
}
/**
* 调用微信接口服务,获取微信用户的openid
*
* @param code
* @return java.lang.String
* @author inbreak
* @create 2024/8/24
**/
private String getOpenid(String code){
// 调用微信服务器,来获取当前微信用户的openId
Map<String, String> map = new HashMap<>();
map.put("appid", weChatProperties.getAppid());
map.put("secret", weChatProperties.getSecret());
map.put("js_code", code);
map.put("grant_type", "authorization_code");
// WX_LOGIN:请求的地址;map:请求的参数
String json = HttpClientUtil.doGet(WX_LOGIN, map);
JSONObject jsonObject = JSON.parseObject(json);
String openid = jsonObject.getString("openid");
return openid;
}
}