统一开放平台实现方案(访微信SDK)

需求分析

在互联中,我们的服务是不对外开放的,但是有先场景下我们可以对外开放,但是必须是系统所允许的用户才可以,这样做一方面保证安全,另一方面可以提升平台的能力,比如调用微信的接口必须要进行微信开发者认证,比如阿里云等等,那么我们如何实现一个自己的开放平台呢?

实现思路

平台接入流程图如下:
在这里插入图片描述
提供一个申请接入的入口,用户通过注册审核通过后获取appid和appserect得到访问应用服务的钥匙,然后通过钥匙获取访问的token.

服务端验证流程图如下
在这里插入图片描述
服务端要验证访问者是不是真实的用户,有时候还可以增加ip白名单进行拦截,具体要根据业务进行扩展,总体思路如上,返回token后,用户就可以拿着token调用服务的API,服务端可以通过aop进行接口统计等等。

服务端验证代码示例

  /**
     * 获取登录token
     *
     * @param body
     * @param request
     * @return
     */
    public String getAccessToken(String body, HttpServletRequest request) {
        log.info("body是:{}", body);
        String appid = request.getHeader("appid");
//        String secret1 = request.getHeader("secret");
        try {
            if (!StringUtils.hasText(body)) {
                throw new ServiceException("必传参数:body不能为空!");
            }
            UserApplicationEntity validAppidAndSecret = this.isValidAppidAndSecret(appid);
            if (validAppidAndSecret==null) {
                throw new ServiceException("appid/secret:验证失败");
            }
            String secret1 = validAppidAndSecret.getSecret();
//            String decode = URLDecoder.decode(body, StandardCharsets.UTF_8);
            log.info("解密后的值是:{}", body);
            String decryptBodyStr = RsaUtil.decryptStr(body, secret1);
            log.info("P{}",decryptBodyStr);
            JSONObject decryptBody = JSONObject.parseObject(decryptBodyStr);
            String secret = decryptBody.getString("secret");
            //验证appid和secret合法性
           if(!secret1.equals(secret)){
               throw new ServiceException("secret:验证失败,请联系管理员");
           }
            Date expiryDate = validAppidAndSecret.getExpiryDate();
            int compare = DateUtil.compare(expiryDate, new Date());
            if(compare<0){
                throw new ServiceException("appid/secret:已过期,请联系管理员");
            }
            //根据当前时间戳和请求时间戳验证是否盗链
            Long timestamp = decryptBody.getLong("timestamp");
            long requestInterval = System.currentTimeMillis() - timestamp;
            if (requestInterval > REQUEST_EXPIRES_TIME) {
                throw new ServiceException("时间已经超时");
            }
            //验证调用方身份合法性(验证签名)
            Optional<String> signOpt = Optional.ofNullable(request.getHeader("sign"));
            if (signOpt.isEmpty()) {
                throw new ServiceException("身份不合法!");
            }
            String grantType = decryptBody.getString("grantType");
            String salt = decryptBody.getString("salt");
            String generatedSign = SecureUtil.md5(appid + secret + grantType + timestamp+salt);
            String sign = signOpt.get();
            if (!sign.equals(generatedSign)) {
                throw new ServiceException("身份不合法!");
            }
            //通过jwt生成access token
            Map<String, Object> payload = new HashMap<>();
            payload.put("appid", appid);
            payload.put("secret", secret);
            payload.put("grantType", grantType);
            payload.put("timestamp", timestamp);
            payload.put("salt", salt);
            payload.put("sign", sign);
            return jwtService.generateAccessToken(appid,payload);
        } catch (Exception e) {
            log.error("验证失败,请联系管理员:{}" , e);
            throw new ServiceException("验证失败,请联系管理员:" + e);
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

stayhungerstayflush

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值
>