卖烤红薯也要懂OAuth2.0

小季临近毕业了,但是他听说最近经济形势不太好,消费降级成为了一个热议的话题。和他最直接相关的就是各大互联网公司缩招了,本身就技术平平的他,这下更为找工作发愁了。

小季刚出校园,对经济理论这些不甚了解,这一时半会也找不到互联网开发相关的岗位,竟有点束手无策了。不过他对信息还是有一定的敏感度,由于大家现在普遍比较穷,很多人不得消费低价的商品。所以网络上出现了一句:“吃着涪陵榨菜,喝着二锅头,出门共享单车,购物拼夕夕。”小季心想,做事情还是得顺势而为,不要老想着逆天。俗话说:上大学不如卖红薯。烤红薯作为典型的快消品,这是妥妥的商机啊。

几年过去了,小季变成了中等季。而他的「初恋红薯」也已经在全国开了100000家连锁,slogan就是「捧在手心,化在口中」。生意做这么大,当然是有独家研制的配方,传闻是这个配方是小季用机器学习训练出来的。

那么问题来了,如何保证独家配方能安全的到达每个门店?小季基于以前学过的OAuth2.0,设计了一个鉴权的流程。

由于全世界门店太多,我们现在和一些第三方的物流中心合作。这些物流中心必须是在「初恋红薯」注册审核过的,才会拥有配送的资格。

上海这一片的配送服务是由一家名为「字节物流」的公司承包的(公众号「字节流」旗下物流公司)。下面我们将角色捋一捋。

门店 = 用户;秘制原料 = 用户数据;物流公司 = 第三方;「初恋红薯」总部 = 数据拥有方

现在上海一家门店S需要通过「字节物流」Z向总部拿原料。

如果是最传统的方式,S把自己的账号密码交给Z,Z把S的账号密码带到总部请求验证。这样就会产生一个问题:假如Z保存了S的账号密码,在S不知情的情况下去骗取原料呢?而S要频繁地修改密码才能防止这个行为,这很麻烦,且不安全。

现在小季基于OAuth2.0设计的方式是这样的:

完成服务后,只要access_token失效,第三方则无法访问数据中心。

到底什么时OAuth?

维基百科给出了这样的解释:

在越来越开放的互联网世界,这是一种常用的授权方式,有效地连接和隔离了系统。

比如我们平时在使用第三方APP或第三方网站时,常常可以使用微信登录,这是微信开放平台给予了第三方的开发者权限,微信的登录权限也是基于OAuth2.0的。下面我们通过一个demo,来了解一下微信登录的流程,可以结合对比「初恋红薯」的例子。

现在我们有一个自己开发的网站,为了给予用户更好的体验,允许用户使用微信登录,而不需要立刻注册账号。

首先我们需要请求微信的授权:https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect

我对其中的几个重要参数具体解释一下:

  1. appid=APPID,APPID是第三方开发者在微信开放平台上注册应用ID
  2. redirect_uri=REDIRECT_URI,若用户同意授权,则回调REDIRECT_URI这个接口,这个接口是开发者部署在自己的服务器上的,用于接受返回的code,并利用code做进一步处理。
  3. response_typescopestate是微信规定的返回类型、权限域、状态,代表了需要请求的资源的种类、适用范围等。具体可以参考微信开放平台的官方文档。

上述参数中,最需要开发者关注的是回调接口,这个需要我们自己编写,以继续后续的操作。下面我用一段简易的Java代码来演示:

// 对外接口
@RequestMapping(path = "/user", method = RequestMethod.GET)
  public ResponseEntity<?> wxcall(@RequestParam(value = "code", required = false) String code,
                                  HttpServletResponse response) {
        User user = weixinService.getWxUserInfo(code);
    }
复制代码
// 根据code获取access_token 和 openid
 public User getWxUserInfo(String code) {
    JsonParser parser = new JsonParser();
    String uri = UriComponentsBuilder
      .fromHttpUrl("https://api.weixin.qq.com/sns/oauth2/access_token")
      .queryParam("appid", WeixinConstants.APPID )
      .queryParam("secret", WeixinConstants.APPSECRET)
      .queryParam("code", code)
      .queryParam("grant_type", "authorization_code")
      .toUriString();
    HttpEntity<String> response = templateProvider.getRestTemplate()
      .exchange(uri, HttpMethod.GET, null, String.class);
    JsonObject accessTokenJson = null;
    try {
      accessTokenJson = parser.parse(response.getBody()).getAsJsonObject();
    } catch (Exception e) {
      e.printStackTrace();
    }
    if (accessTokenJson == null || !accessTokenJson.has("access_token")) {
      logger.error("fetch accesstoken error {}", response.getBody());
      return null;
    }
// 获取 用户信息
    String infoUri = UriComponentsBuilder
      .fromHttpUrl("https://api.weixin.qq.com/sns/userinfo")
      .queryParam("access_token", accessTokenJson.get("access_token").getAsString())
      .queryParam("openid", accessTokenJson.get("openid").getAsString())
      .queryParam("lang", "zh_CN")
      .toUriString();
    HttpEntity<String> userInfo = templateProvider.getRestTemplate()
      .exchange(infoUri, HttpMethod.GET, null, String.class);
    JsonObject userInfoJson = null;
    try {
      userInfoJson = parser.parse(userInfo.getBody()).getAsJsonObject();
    } catch (Exception e) {
      e.printStackTrace();
    }
    if (userInfoJson == null ||
      (userInfoJson.has("errcode") && userInfoJson.get("errcode").getAsInt() != 0)) {
      logger.error("fetch userinfo error {}", userInfo.getBody());
      return null;
    }

复制代码

此时,用户的基本信息已经封装在了userInfoJson中,可以享用了。

这样一来,「初恋红薯」的秘制原料就能在可控安全的范围内运输使用了。小季步入中年,看着自己的连锁店在神州大地上星罗棋布,不禁露出了优雅的成功中年男人の微笑。

突然,室友摇醒了梦中的小季。“快醒醒!你的邮箱里收到offer啦!”小季这才惊觉原来是南柯一梦,打开邮箱,邮件上赫然写着:月薪4k包吃住。


如今基于微信的公众号、小程序开发如火如荼,如果你想要尝试,可以先购置一台自己的云主机,每月仅需8元,另外添加微信,我会返还优惠红包,我觉得初学者都需要一台云主机学习实践。推荐阅读:为什么说初学者都需要一台云服务器

购买链接:m.aliyun.com/act/team111…

我的微信,欢迎交流

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值