钉钉微应用免登实现

  用户在使用软件应用的过程中,第一步往往都是登录。输入账号密码,进行登录,登录的目的就是让应用识别张三是张三,而不是李四。相对应,如果能够不用输账号密码,应用就知道你是你,就叫做免登。
  免登的源头还是需要登录的。业内企业内部登录往往采用统一登录中心SSO的方案,比如集成CAS。一个同一地址登录,同一域名下采用识别cookie的方式解析用户名。也就是,登录了OA之后,访问HR、邮箱等等,在关闭浏览器之前,不需要再次登录。钉应用实现免登,本质上也是通过钉钉实现登录。因为使用者已经输入账号密码或者手机号验证码在钉钉实现了登录,钉钉已经保存了用户的信息。

具体实践,实现钉应用免登可以分为下面几个步骤。
1、钉应用用户信息与钉钉通讯录打通。比如用户通过手机号实现关联。
2、前端代码,调用JSapi获取免登授权码。
3、后端代码,调用服务端接口解析授权码,实现登录。
4、后端代码,识别用户后,实现登录逻辑。

  下面用后台java代码和前端vue代码来实际说明。
  通讯录的同步忽略了,按照钉钉服务端接口能够实现同步。我们直接看前端的获取免登授权码该如何获取。

loginByCode(corpId) {
  const _this = this;
  console.log("requestAuthCode begin");
  _this.dd.runtime.permission.requestAuthCode({
    corpId: corpId,
    onSuccess: function (result) {
      console.log("requestAuthCode:" + result.code);
      _this.httpUtils.appGet('/login/loginByCode?code=' + result.code).then(function (res) {
        const user = res.data;
        window.localStorage.setItem("user", JSON.stringify(user));
      }, function (r) {
        _this.commonUtils.commonAlert(r.msg);
      })
    },
    onFail: function (err) {
      alert("客户端-获取免登授权码失败:" + JSON.stringify(err));
    }
  })
},

  上面的代码块封装了loginByCode的方法,其主要功能就是获取授权码,然后将授权码传到后台,获取用户信息。关键的代码就是

dd.runtime.permission.requestAuthCode

  这一个函数需要传入一个corpId作为参数,该参数在企业后台能够找到。获取授权码失败,我们可以把错误信息弹框显示出来。获取成功,就可以请求后台的接口拉取用户信息。接下来看看后台是如何实现的。

@GetMapping("loginByCode")
public UserVO list(@RequestParam String code) {
    log.info(code);
    UserInfoByCodeResponse response = userInfoByCodeRequest.get(code);
    return dingUserQueryService.getVOByUserId(response.getUserid());
}

  上图后端代码展示了获取用户信息的顺序,即先解析授权码,得到用户信息,然后再去匹配用户信息,找到当前的用户。这里简化了登录的业务步骤,如果有集成鉴权,这一块是需要另写代码实现。接下来详细了解下userInfoByCodeRequest做了什么。

private String userInfoUrl = "https://oapi.dingtalk.com/user/getuserinfo?access_token={accessToken}&code={code}";

public UserInfoByCodeResponse get(String code) {
    Map<String, Object> param = tokenService.getTokenMap();
    param.put("code",code);
    return requestUtils.getWithUrlParam(userInfoUrl, UserInfoByCodeResponse.class, param);
}

  如图所示,其实就是做了个请求,请求URL关键标识为user/getuserinfo。钉钉会返回用户数据,且钉钉返回的数据会包含userid,通过userid这一数据在应用从钉钉通讯录同步过来的数据中,即可定位到一位用户,这也就是下面这行代码做的事情。

dingUserQueryService.getVOByUserId(response.getUserid()

  注意这行代码是完全在应用内实现的,比如笔者这里就是去数据库根据userid查找用户,返回用户信息。至此,微应用免登就实现完毕,是不是很简单呢。觉得简单就点个赞留个言吧,有问题欢迎联系笔者共同探讨。

posted @ 2019-07-04 14:20  小拓同学  阅读(4210)  评论(0编辑  收藏  举报