马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
一. 微信小步调授权登录
引入依靠
- <!--微信小程序-->
- <dependency>
- <groupId>com.github.binarywang</groupId>
- <artifactId>weixin-java-miniapp</artifactId>
- <version>4.3.0</version>
- </dependency>
复制代码
修改设置文件
- wx:
- # 微信小程序appid
- app-id: wxcbxxxxxxxxxxxxxxx
- # 小程序密钥
- app-secret: 8ccxxxxxxxxxxxxxxxx
- msgDataFormat: JSON
复制代码
设置类Properties
- import lombok.Data;
- import lombok.ToString;
- import org.springframework.boot.context.properties.ConfigurationProperties;
- import org.springframework.stereotype.Component;
- /**
- * @Author:Ccoo
- * @Date:2024/3/21 20:40
- */
- @Data
- @ToString
- @Component
- @ConfigurationProperties(prefix = "wx")
- public class WxProperties {
- /**
- * 设置微信小程序的appid
- */
- private String appId;
- /**
- * 设置微信小程序的Secret
- */
- private String appSecret;
- /**
- * 消息格式,XML或者JSON
- */
- private String msgDataFormat;
- }
复制代码
设置类Config
- import cn.binarywang.wx.miniapp.api.WxMaService;
- import cn.binarywang.wx.miniapp.api.WxMaUserService;
- import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
- import cn.binarywang.wx.miniapp.api.impl.WxMaUserServiceImpl;
- import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
- import lombok.extern.slf4j.Slf4j;
- import me.chanjar.weixin.common.error.WxRuntimeException;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import javax.annotation.Resource;
- import java.util.HashMap;
- import java.util.Objects;
- @Slf4j
- @Configuration
- public class WxMaConfiguration {
- @Resource
- private WxProperties wxProperties;
- @Bean
- public WxMaService wxMaService() {
- if (Objects.isNull(wxProperties)) {
- throw new WxRuntimeException("请添加下相关配置, 注意别配错了!");
- }
- WxMaService maService = new WxMaServiceImpl();
- try {
- WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl();
- config.setAppid(wxProperties.getAppId());
- config.setSecret(wxProperties.getAppSecret());
- config.setMsgDataFormat(wxProperties.getMsgDataFormat());
- HashMap configMap = new HashMap<>();
- configMap.put(config.getAppid(), config);
- maService.setMultiConfigs(configMap);
- } catch (Exception e) {
- throw new WxRuntimeException("微信小程序相关配置配置失败!");
- }
- return maService;
- }
- }
复制代码
Controller控制器代码
- import com.itheima.mp.domain.R;
- import com.itheima.mp.service.WeChatService;
- import io.swagger.annotations.ApiOperation;
- import io.swagger.annotations.ApiParam;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.web.bind.annotation.PostMapping;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RequestParam;
- import org.springframework.web.bind.annotation.RestController;
- /**
- * <p>
- * 前端控制器
- * </p>
- *
- * @author Ccoo
- * @since 2023-10-01
- */
- @RestController
- @RequestMapping("/wechat")
- public class WeChatController {
- @Autowired
- private WeChatService wechatService;
- @ApiOperation(value = "微信小程序授权登录", notes = "微信小程序授权登录")
- @PostMapping("/wxLogin")
- public R<?> wxLogin(@ApiParam("loginCode") @RequestParam String code) {
- return wechatService.wxLogin(code);
- }
- }
复制代码
Service接口层代码
- import com.itheima.mp.domain.R;
- /**
- * @author Ccoo
- * 2024/8/23
- */
- public interface WeChatService {
- /**
- * 微信授权登录
- * @param code 授权码
- * @return 结果
- */
- R<?> wxLogin(String code);
- }
复制代码
ServiceImpl实现层代码
- import cn.binarywang.wx.miniapp.api.WxMaService;
- import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
- import cn.hutool.json.JSONUtil;
- import lombok.RequiredArgsConstructor;
- import lombok.extern.slf4j.Slf4j;
- import me.chanjar.weixin.common.error.WxErrorException;
- import org.springframework.stereotype.Service;
- /**
- * @author Ccoo
- * 2024/8/23
- */
- @Slf4j
- @Service
- @RequiredArgsConstructor
- public class WeChatServiceImpl implements WeChatService {
- private final WxMaService wxMaService;
- /**
- * 微信授权登录
- *
- * @param code 授权码
- * @return 结果
- */
- @Override
- public R<?> wxLogin(String code) {
-
- try {
- WxMaJscode2SessionResult sessionInfo = wxMaService.getUserService().getSessionInfo(code);
- String info = JSONUtil.toJsonStr(sessionInfo);
- log.info("微信授权登录成功:{}", info);
- return R.ok(info);
- } catch (WxErrorException e) {
- log.error("微信授权登录失败:{}", e.getError().getErrorMsg());
- return R.fail(e.getError().getErrorCode(), e.getError().getErrorMsg());
- }
- }
- }
复制代码
同一相应类 R
- import java.io.Serializable;
- /**
- * 响应信息主体
- *
- * @author Ccoo
- */
- public class R<T> implements Serializable
- {
- private static final long serialVersionUID = 1L;
- /** 成功 */
- public static final int SUCCESS = 200;
- /** 失败 */
- public static final int FAIL = 500;
- private int code;
- private String msg;
- private T data;
- public static <T> R<T> ok()
- {
- return restResult(null, SUCCESS, "操作成功");
- }
- public static <T> R<T> ok(String msg)
- {
- return restResult(null, SUCCESS, msg);
- }
- public static <T> R<T> ok(T data)
- {
- return restResult(data, SUCCESS, "操作成功");
- }
- public static <T> R<T> ok(T data, String msg)
- {
- return restResult(data, SUCCESS, msg);
- }
- public static <T> R<T> fail()
- {
- return restResult(null, FAIL, "操作失败");
- }
- public static <T> R<T> fail(String msg)
- {
- return restResult(null, FAIL, msg);
- }
- public static <T> R<T> fail(T data)
- {
- return restResult(data, FAIL, "操作失败");
- }
- public static <T> R<T> fail(T data, String msg)
- {
- return restResult(data, FAIL, msg);
- }
- public static <T> R<T> fail(int code, String msg)
- {
- return restResult(null, code, msg);
- }
- private static <T> R<T> restResult(T data, int code, String msg)
- {
- R<T> apiResult = new R<>();
- apiResult.setCode(code);
- apiResult.setData(data);
- apiResult.setMsg(msg);
- return apiResult;
- }
- public int getCode()
- {
- return code;
- }
- public void setCode(int code)
- {
- this.code = code;
- }
- public String getMsg()
- {
- return msg;
- }
- public void setMsg(String msg)
- {
- this.msg = msg;
- }
- public T getData()
- {
- return data;
- }
- public void setData(T data)
- {
- this.data = data;
- }
- }
复制代码
具体授权登录代码
微信小步调授权登录思路 :
- 先判断Redis中缓存是否命中, 如果命中则直接返回缓存信息
- 如果未命中缓存, 则使用暂时校验码code去微信调换openid
- 查询数据库该openid对应用户信息是否存在, 存在则直接返回, 不存在则注册用户信息
- 最后将用户信息存入redis, 并返回相应的token供下次授权登录前判断是否缓存信息
具体实当代码如下
- @ApiOperation("微信授权登录")
- @PostMapping("/customer_login")
- public R<SysWxUser> customerLogin(@RequestBody WXAuth wxAuth) {
- return weixinService.customerLogin(wxAuth);
- }
复制代码- R<SysWxUser> customerLogin(WXAuth wxAuth);
复制代码- /**
- * 授权登录
- *
- * @param wxAuth 授权信息
- * @return 结果
- */
- @Override
- public R<SysWxUser> customerLogin(WXAuth wxAuth) {
- String code = wxAuth.getCode();
- String iv = wxAuth.getIv();
- String token = wxAuth.getToken();
- String encryptedData = wxAuth.getEncryptedData();
- if(StrUtil.isBlank(code) && StrUtil.isBlank(token)){
- return R.fail(MessageConstants.PARAMS_ERROR);
- }
- // 判断登录态是否在有效期
- if(StrUtil.isNotBlank(token)){
- // token不为空 判断token是否过期
- String content = redisTemplate.opsForValue().get(RedisKey.WX_SESSION_KEY + token);
- if(content == null){
- return R.fail(MessageConstants.TOKEN_NOT_EXIST);
- }
- // 查询token对应用户信息
- SysWxUser info = JSONUtil.toBean(content, SysWxUser.class);
- // 刷新token有效时间
- redisTemplate.opsForValue().set(RedisKey.WX_SESSION_KEY + token, content, 3600, TimeUnit.SECONDS);
- return R.ok(info);
- }
- SysWxUser wxUser = null;
- WxMaJscode2SessionResult sessionInfo = null;
- try {
- sessionInfo = wxMaService.getUserService().getSessionInfo(code);
- WxMaUserInfo userInfo = wxMaService.getUserService().getUserInfo(sessionInfo.getSessionKey(), encryptedData, iv);
-
- String openid = sessionInfo.getOpenid();
-
- // 使用微信openId查询是否有此用户(WxUser)
- wxUser = lambdaQuery().eq(SysWxUser::getOpenid, openid).one();
-
- // 不存在 构建用户信息进行注册
- if(wxUser == null) {
- wxUser = new SysWxUser();
- wxUser.setOpenid(openid);
- wxUser.setWxName(Constants.WX_PREFIX + RandomUtil.randomString(6));
- wxUser.setAvatarUrl(userInfo.getAvatarUrl());
- int insert = wxUserMapper.insert(wxUser);
- if (insert == 0) {
- return R.fail(MessageConstants.USER_BIND_ERROR);
- }
- }
-
- } catch (Exception e) {
- e.printStackTrace();
- log.error(MessageConstants.SYSTEM_ERROR);
- }
- String sessionKey = sessionInfo.getSessionKey();
- String cacheKey = RedisKey.WX_SESSION_KEY + sessionKey;
- // 将 openid / sessionKey 存入redis
- redisTemplate.opsForValue().set(cacheKey, JSONUtil.toJsonStr(wxUser), 3600, TimeUnit.SECONDS);
- return R.ok(wxUser,Constants.TOKEN_PRE + sessionKey);
- }
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |