微信支付篇---微信账号登陆小程序

微信账号登陆小程序

我们先要实现支付流程,首先必须要做的是,给小程序实现微信登陆的功能。大家回顾一下第一幅时序图,也就是创建支付订单的那副时序图。首先由小程序发起请求给商户系统,让商户系统申请创建支付订单。各位同学你仔细想一想,如果是POSTMAN软件,或者HTTPClient这样的客户端程序,模拟小程序发出请求,他们根本都不是真实的用户,而且也没有登陆小程序,所以商户系统必须要加以判断。
在这里插入图片描述

其实想要判断到底是不是真实的用户发来的请求,我们只需要判断两样东西即可。一个是OpenID,另一个是Token字符串。用户在手机上用微信账号登陆小程序的时候,会产生一个唯一的OpenID值,商户系统会记录下这个OpenID值。如果商户系统接收到的请求里面没有OpenID值,或者OpenID值跟数据库里面的对不上,就说明这不是一个合法的用户。那么商户系统就不用理会这个请求。仅仅OpenID能核对上还不行,我还要看看发起请求的用户是不是已经登陆了小程序。只有用户登陆小程序之后,才可以证明是本人下单支付,所以商户系统必须要判断用户到底有没有登陆小程序。因为我们搭建的后端项目,整合了Shiro和JWT技术,所以成功登陆小程序的用户,后端系统都会返回一个Token字符串。小程序每次发起请求的时候都要带上这个令牌字符串,告诉renren-fast后端系统,我现在已经登陆了。当然了,后端系统也要验证这个Token字符串是否有效,以及过没过期。
在这里插入图片描述

  1. 表单校验:使用ValidatorUtils.validateEntity(form)对传入的表单数据进行校验。
    获取微信登录信息:构造了一个包含微信小程序的appId、appSecret、用户登录凭证js_code和授权类型grant_type的请求参数map。
  • map.put(“appid”, appId);
    这行代码将appid键和appId变量的值放入到一个名为map的HashMap对象中。appid是微信小程序的唯一标识,通常在微信开发者平台注册小程序时获得。
  • map.put(“secret”, appSecret);
    这行代码将secret键和appSecret变量的值放入到map中。appSecret是微信小程序的密钥,与appid一起用于验证请求的安全性。
  • map.put(“js_code”, form.getCode());
    这行代码将js_code键和form.getCode()方法返回的值放入到map中。js_code是用户在小程序中授权后,小程序前端通过调用微信API获得的一个临时授权凭证。form.getCode()方法应该是从一个表单对象中获取这个js_code。
  • map.put(“grant_type”, “authorization_code”);
    这行代码将grant_type键和字符串"authorization_code"放入到map中。grant_type参数用于指定授权类型,这里使用"authorization_code"表示使用的是授权码模式。
  1. 发送请求:使用HttpUtil.post(url, map)向微信的jscode2session接口发送请求,执行这段代码后,response变量将包含微信服务器返回的响应。这个响应通常是一个JSON格式的字符串,其中包含了access_token(访问令牌)和openid(用户的openid)。openid是用户在当前小程序中的唯一标识符,可以用来识别用户。

  2. 解析响应:将响应结果解析为JSON对象,并尝试获取openid。

  3. 用户信息处理:检查openid是否存在,如果不存在,返回错误信息(判断微信请求是否正确)。

  4. 用户信息查询与创建:查询数据库中是否存在对应的用户,如果不存在,则创建一个新用户,并保存到数据库。

  5. 生成Token:使用jwtUtils.generateToken(id)生成一个JWT Token。

  6. 准备返回结果:将生成的Token和Token的过期时间放入一个Map中。
    返回结果:使用R.ok(result)返回成功响应,其中R是一个自定义的响应实体类。

核心实现代码

 @RestController
 @RequestMapping("/app/wx")
 @Api("微信业务接口")
 public class WxController {
     @Value("${application.wxpay.app-id}")
     private String appId;

     @Value("${application.wxpay.app-secret}")
     private String appSecret;

     @Value("${application.wxpay.key}")
     private String key;

     @Value("${application.wxpay.mch-id}")
     private String mchId;

     @Autowired
     private UserService userService;

     @Autowired
     private OrderService orderService;

     @Autowired
     private JwtUtils jwtUtils;

     @Autowired
     private MyWXPayConfig myWXPayConfig;

     @PostMapping("login")
     @ApiOperation("登录")
     public R login(@RequestBody WxLoginForm form) {
         //表单校验
         ValidatorUtils.validateEntity(form);
         String url = "https://api.weixin.qq.com/sns/jscode2session";
         HashMap map = new HashMap();
         map.put("appid", appId);
         map.put("secret", appSecret);
         map.put("js_code", form.getCode());
         map.put("grant_type", "authorization_code");
         String response = HttpUtil.post(url, map);
         JSONObject json = JSONUtil.parseObj(response);
         String openId = json.getStr("openid");
         if (openId == null || openId.length() == 0) {
             return R.error("临时登陆凭证错误");
         }
         UserEntity user = new UserEntity();
         user.setOpenId(openId);
         QueryWrapper wrapper = new QueryWrapper(user);
         int count = userService.count(wrapper);
         if (count == 0) {
             user.setNickname(form.getNickname());
             user.setPhoto(form.getPhoto());
             user.setType(2);
             user.setCreateTime(new Date());
             userService.save(user);
         }
         // 重新new一个User,并且设置openId的原因是因为:
         // 之前设置的user里有其他属性,而我们只想根据openid来进行查询
         user = new UserEntity();
         user.setOpenId(openId);  
         wrapper = new QueryWrapper(user);
         user = userService.getOne(wrapper);
         long id = user.getUserId();

         String token = jwtUtils.generateToken(id);
         Map<String, Object> result = new HashMap<>();
         result.put("token", token);
         result.put("expire", jwtUtils.getExpire());

         return R.ok(result);
     }
 }

  • 36
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值