实现网站应用钉钉扫码登录,及查询用户详细信息

来源:互联网 发布:网站源码打包下载 编辑:程序博客网 时间:2024/06/06 09:05

第一步,看官方文档

网站应用钉钉扫码登录开发指南(钉钉官网)

如果你想要通过用户扫码获取到他的个人信息,那么你需要完成全部的交互,如果你只是想为你的网站做一个免登录处理,其实只要拿到用户的

第三步,创建一个用户扫码界面并获取临时code

官网一共给大家提供了两种方式,第一种就是直接跳转到钉钉的二维码扫描;第二种是嵌入到自己的网页显示二维码。

因为我用的是第一种,并且这篇博客也仅仅是建立在初步实现,所以这里就不为大家介绍第二种嵌入方式了。

https://oapi.dingtalk.com/connect/qrconnect?appid=APPID&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=REDIRECT_URI

将自己的appid填写在APPID处,将自己希望扫码后跳转到的地址填写在REDIRECT_URI,比如可以填写为http://google.com/dingtalkLogin或者http://google.com/dingtalkLogin.action等等,大家可以根据自己的实际情况填写。

  • 获取临时code和参数state,首先再看一次官网说明文档: 
    这里写图片描述 
    所以你在REDIRECT_URI跳转回去的方法中,需要获取到code和state两个参数。而关于state,参数其实就是你在之前拼接URL的时候中的STATE,这里建议大家可以使用时间戳(当用户访问的时候,因为URL不同,所以浏览器会重新获取,避免浏览器因缓存而导致二维码无法使用等问题);

代码:

  • 拼接URL:
    /**     *      * 描述:后台默认跳转到二维码登录界面     * 开发人员:暴沸     * 开发时间: 2017年2月23日 下午9:09:57     * 联系方式:admin@baofeidyz.com      *     * @param request     */    @RequestMapping(value="login")    public void toALiDingDing(HttpServletResponse response){        //这是我自己写的一个获取时间戳的Util,前期大家可以不管这个STATE        TimeUtil timeUtil = new TimeUtil();        StringBuilder stringBuilder = new StringBuilder();        stringBuilder.append("https://oapi.dingtalk.com/connect/qrconnect?appid=APPID&")            .append("response_type=code&scope=snsapi_login&state=")            .append(timeUtil.getNow()) 

.append("&redirect_uri=")openid就可以了。当然我会在这篇博客中贴出全部步骤的代码。

第二步,获取appId和appSecret

  • 登录/注册到钉钉开发者官网:新版开发者平台:http://open-dev.dingtalk.com
  • 在左侧的五个菜单中点击自助工具,然后在右侧的菜单中创建扫码登录应用授权,然后依次输入名称描述授权页面logo地址(这个图片最后会出现在用户扫码设备中,建议使用压缩图片减少用户加载时间)、回调域名(一般都是写一个子域名,比如http://oa.dingtalk.com),保存之后便可以看到对应的appId以及appSecret了。
            .append("REDIRECT_URI");        try {            response.sendRedirect(stringBuilder.toString());        } catch (IOException e1) {        }    }

第四步,获取access_token

  • 首先我们还是看一下官方说明文档: 
    这里写图片描述 
    获取钉钉开放应用的ACCESS_TOKEN(钉钉官网) 
    所以我们需要使用java代码向钉钉服务器端发送一个GET请求

关于Java如何封装get和post请求可以参考一下我自己写的博客: 
【JavaWeb开发】用Apache的HttpClient4.5完成HttpGet请求 
【JavaWeb开发】用Apache的HttpClient4.5完成HttpPost请求

        //获取accesstoken        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();        HttpClient httpClient = httpClientBuilder.build();        HttpResponse httpResponse = null;        String url = "https://oapi.dingtalk.com/sns/gettoken?appid=APPID&appsecret=APPSECRET";        HttpGet httpGet = new HttpGet(url);        try {            httpResponse = httpClient.execute(httpGet);        } catch (Exception e) {        }        BufferedReader bufferedReader = null;        StringBuilder entityStringBuilder=new StringBuilder();          //得到httpResponse的状态响应码          int statusCode=httpResponse.getStatusLine().getStatusCode();          if (statusCode==HttpStatus.SC_OK) {              //得到httpResponse的实体数据              HttpEntity httpEntity=httpResponse.getEntity();              if (httpEntity!=null) {                  try {                      bufferedReader=new BufferedReader                      (new InputStreamReader(httpEntity.getContent(), "UTF-8"), 8*1024);                      String line=null;                      while ((line=bufferedReader.readLine())!=null) {                          entityStringBuilder.append(line+"/n");                      }                  } catch (Exception e) {                  }              }          }        JSONObject jsonObject = new JSONObject(entityStringBuilder.toString());        String access_token = jsonObject.getString("access_token");

第五步,获取持久授权码persistent_code

获取用户授权的持久授权码(钉钉官网)

在官网文档中指出,需要使用之前获取到的临时code以及access_token两个参数来发送一个POST请求:

        //获取用户授权的持久授权码        String url3 = "https://oapi.dingtalk.com/sns/get_persistent_code?access_token="+access_token;        System.out.println("url3="+url3);        HttpPost httpPost3 = new HttpPost(url3);        //封装临时授权码        JSONObject jsonObject3_1 = new JSONObject();        jsonObject3_1.put("tmp_auth_code", code);         HttpEntity httpEntity3 = null;        httpEntity3 = new StringEntity(jsonObject3_1.toString(),"UTF-8");        httpPost3.setEntity(httpEntity3);        HttpResponse httpResponse3 = null;        try {            httpResponse3 = httpClient.execute(httpPost3);        } catch (Exception e) {            // TODO: handle exception        }        StringBuilder entityStringBuilder3=new StringBuilder();        //得到httpResponse的状态响应码          int statusCode3=httpResponse3.getStatusLine().getStatusCode();          if (statusCode3==HttpStatus.SC_OK) {              //得到httpResponse的实体数据              HttpEntity httpEntity3_2=httpResponse3.getEntity();              if (httpEntity3!=null) {                  try {                      bufferedReader=new BufferedReader                      (new InputStreamReader(httpEntity3_2.getContent(), "UTF-8"), 8*1024);                      String line=null;                      while ((line=bufferedReader.readLine())!=null) {                          entityStringBuilder3.append(line+"/n");                      }                  } catch (Exception e) {                      e.printStackTrace();                  }              }          }        JSONObject jsonObject3_2 = new JSONObject(entityStringBuilder3.toString());        String persistent_code = jsonObject3_2.getString("persistent_code");        String openid = jsonObject3_2.getString("openid");

如果你自习看代码,在这一步中我们已经拿到了用户在这个网页应用中的唯一标识openid了,其实到这里就可以实现网站的免登录扫码了哦!

第六步,获取SNS_TOKEN

获取用户授权的SNS_TOKEN(钉钉官网)

文档指出,我们需要在POST请求中封装之前获取到的access_token、openid以及persistent_code

        //获取用户授权的SNS_TOKEN        String url4 = "https://oapi.dingtalk.com/sns/get_sns_token?access_token="+access_token;        HttpPost httpPost4 = new HttpPost(url4);        JSONObject jsonObject4 = new JSONObject();        jsonObject4.put("openid", openid);        jsonObject4.put("persistent_code", persistent_code);        HttpEntity httpEntity4 = null;        httpEntity4 = new StringEntity(jsonObject4.toString(),"UTF-8");        httpPost4.setEntity(httpEntity4);        HttpResponse httpResponse4 = null;        //重新获取一个新的httpClient        HttpClientBuilder httpClientBuilder2 = HttpClientBuilder.create();        HttpClient httpClient2 = httpClientBuilder2.build();        try {            httpResponse4 = httpClient2.execute(httpPost4);        } catch (Exception e) {            // TODO: handle exception        }        StringBuilder entityStringBuilder4=new StringBuilder();        //得到httpResponse的状态响应码          int statusCode4=httpResponse4.getStatusLine().getStatusCode();          if (statusCode4==HttpStatus.SC_OK) {              //得到httpResponse的实体数据              HttpEntity httpEntity4_1=httpResponse4.getEntity();              if (httpEntity4_1!=null) {                  try {                      bufferedReader=new BufferedReader                      (new InputStreamReader(httpEntity4_1.getContent(), "UTF-8"), 8*1024);                      String line=null;                      while ((line=bufferedReader.readLine())!=null) {                          entityStringBuilder4.append(line+"/n");                      }                  } catch (Exception e) {                      e.printStackTrace();                  }              }          }        //        JSONObject jsonObject4_1 = new JSONObject(entityStringBuilder4.toString());        String sns_token = jsonObject4_1.getString("sns_token");

胜利就在眼前了!

第七步,获取用户信息

获取用户授权的个人信息(钉钉官网)

直接发送GET请求即可!

        //获取用户授权的个人信息        String url5 = "https://oapi.dingtalk.com/sns/getuserinfo?sns_token="+sns_token;        HttpGet httpGet5 = new HttpGet(url5);        HttpResponse httpResponse5 = null;        try {            HttpClient httpClient3 = httpClientBuilder.build();            httpResponse5 = httpClient3.execute(httpGet5);        } catch (Exception e) {            // TODO: handle exception        }        StringBuilder entityStringBuilder5=new StringBuilder();        //得到httpResponse的状态响应码          int statusCode5=httpResponse5.getStatusLine().getStatusCode();          if (statusCode5==HttpStatus.SC_OK) {              //得到httpResponse的实体数据              HttpEntity httpEntity5=httpResponse5.getEntity();              if (httpEntity5!=null) {                  try {                      bufferedReader=new BufferedReader                      (new InputStreamReader(httpEntity5.getContent(), "UTF-8"), 8*1024);                      String line=null;                      while ((line=bufferedReader.readLine())!=null) {                          entityStringBuilder5.append(line+"/n");                      }                  } catch (Exception e) {                      e.printStackTrace();                  }              }          }        JSONObject jsonObject5_1 = new JSONObject(entityStringBuilder5.toString());        JSONObject jsonObject5 = jsonObject5_1.getJSONObject("user_info");        String nick = jsonObject5.getString("nick");        String unionid = jsonObject5.getString("unionid");        String dingId = jsonObject5.getString("dingId");
//-----------------------------------------以下为博主(Happy王子乐)代码原创,最后会贴出完成代码   ------------//

第八步:根据unionid获取用户userId   (以下代码和上述代码不配套,最后贴出完整配套代码;PS:钉钉官方文档比较坑,其中有两个access_token,以下接口是使用的另一个access_token)

String appAccessToken = getAppAccesstoken();String userId = getUserId(appAccessToken, unionId);
public String getAppAccesstoken() {    String url = "https://oapi.dingtalk.com/gettoken?corpid=dingbbe74ca7c844b45f35c2f4657eb6378f&corpsecret=MERA4ADae_62lU05Y9fbU9Z43NZBoIBTHnam1SGiKgblcO_NKIzEts-2G3Ji5njw";    JSONObject json = ossHttpGetUtil(url);    if(null!=json){        if (Integer.parseInt(json.get("errcode").toString()) == 0) {            String appAccessToken = json.getString("access_token");            return appAccessToken;        }    }    return "";}public JSONObject getPersistentCode(String accessToken,String code) {    String url = "https://oapi.dingtalk.com/sns/get_persistent_code?access_token=" + accessToken;    JSONObject jsonData = new JSONObject();    jsonData.put("tmp_auth_code", code);    JSONObject json = ossHttpPostUtil(url, jsonData);    if(null!=json){        if (Integer.parseInt(json.get("errcode").toString()) == 0) {            return json;        }    }    return null;}

第九步:根据userId获取用户详细数据
JSONObject userData = getUserData(appAccessToken, userId);
public JSONObject getUserData(String accessToken, String userId) {    String url = "https://oapi.dingtalk.com/user/get?access_token="+accessToken+"&userid="+userId;    JSONObject json = ossHttpGetUtil(url);    if(null!=json){        if (Integer.parseInt(json.get("errcode").toString()) == 0) {            return json;        }    }    return null;}



//-----------------------以下是从回掉地址传入code,到查询用户详细信息,完成代码,个人原创(Happy王子乐)


package com.hqq.api.staff.services.impl;import com.alibaba.fastjson.JSONObject;import com.hqq.api.staff.entitis.Staff;import com.hqq.api.staff.repos.StaffRepo;import com.hqq.api.staff.services.StaffService;import org.apache.http.HttpEntity;import org.apache.http.HttpResponse;import org.apache.http.HttpStatus;import org.apache.http.client.HttpClient;import org.apache.http.client.methods.HttpGet;import org.apache.http.client.methods.HttpPost;import org.apache.http.entity.StringEntity;import org.apache.http.impl.client.HttpClientBuilder;import org.apache.http.util.EntityUtils;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.domain.Example;import org.springframework.data.domain.Page;import org.springframework.data.domain.PageRequest;import org.springframework.data.domain.Sort;import org.springframework.stereotype.Service;import java.io.BufferedReader;import java.util.List;/** * Created by kevinzou on 30/07/2017. * StaffServiceImpl */@Servicepublic class StaffServiceImpl implements StaffService {    @Autowired    private StaffRepo repo;    @Override    public Staff save(Staff entity) {        return repo.save(entity);    }    @Override    public void delete(Long id) {        repo.delete(id);    }    @Override    public void delete(Staff entity) {        repo.delete(entity);    }    @Override    public Staff findById(Long id) {        return repo.findOne(id);    }    @Override    public Staff findBySample(Staff sample) {        return repo.findOne(Example.of(sample));    }    @Override    public List<Staff> findAll() {        return repo.findAll();    }    @Override    public List<Staff> findAll(Sort sort) {        return repo.findAll(sort);    }    @Override    public List<Staff> findBySamples(Staff sample) {        return repo.findAll(Example.of(sample));    }    @Override    public List<Staff> findBySamples(Staff sample, Sort sort) {        return repo.findAll(Example.of(sample), sort);    }    @Override    public Page<Staff> findBySamples(Staff sample, PageRequest pageRequest) {        return repo.findAll(Example.of(sample), pageRequest);    }    @Override    public Page<Staff> findBySamples(PageRequest pageRequest) {        return repo.findAll(pageRequest);    }    @Override    public JSONObject goDingLogin(String code) {        try{            //获取accesstoken            String accessToken = getAccesstoken();            //获取用户授权的持久授权码            JSONObject json = getPersistentCode(accessToken, code);            String openId = "";            String persistentCode = "";            if(null!=json){                openId = json.getString("openid");                persistentCode = json.getString("persistent_code");            }            //获取用户授权的SNS_TOKEN            String snsToken = getSnsToken(accessToken, openId, persistentCode);            //获取用户unionid            String unionId = getUnionId(snsToken);            //根据unionid获取用户userId            String appAccessToken = getAppAccesstoken();            String userId = getUserId(appAccessToken, unionId);            //获取用户详细数据            JSONObject userData = getUserData(appAccessToken, userId);            return userData;        }catch (Exception e){        }        return null;    }    public String getAccesstoken() {        String url = "https://oapi.dingtalk.com/sns/gettoken?appid=dingoap77h68gih6szglb4&appsecret=ZUGaKf3pvd6DDtVEpjdISmjCv_Sq1VNH0Oe8v_nfockMKIQth03KWwSS5fzRIM5o";        JSONObject json = ossHttpGetUtil(url);        if(null!=json){            if (Integer.parseInt(json.get("errcode").toString()) == 0) {                String accessToken = json.getString("access_token");                return accessToken;            }        }        return "";    }    public String getAppAccesstoken() {        String url = "https://oapi.dingtalk.com/gettoken?corpid=dingbbe74ca7c844b45f35c2f4657eb6378f&corpsecret=MERA4ADae_62lU05Y9fbU9Z43NZBoIBTHnam1SGiKgblcO_NKIzEts-2G3Ji5njw";        JSONObject json = ossHttpGetUtil(url);        if(null!=json){            if (Integer.parseInt(json.get("errcode").toString()) == 0) {                String appAccessToken = json.getString("access_token");                return appAccessToken;            }        }        return "";    }    public JSONObject getPersistentCode(String accessToken,String code) {        String url = "https://oapi.dingtalk.com/sns/get_persistent_code?access_token=" + accessToken;        JSONObject jsonData = new JSONObject();        jsonData.put("tmp_auth_code", code);        JSONObject json = ossHttpPostUtil(url, jsonData);        if(null!=json){            if (Integer.parseInt(json.get("errcode").toString()) == 0) {                return json;            }        }        return null;    }    public String getSnsToken(String accesstoken, String openid, String persistent_code) {        String url = "https://oapi.dingtalk.com/sns/get_sns_token?access_token="+accesstoken;        HttpPost httpPost = new HttpPost(url);        JSONObject jsonData = new JSONObject();        jsonData.put("openid", openid);        jsonData.put("persistent_code", persistent_code);        JSONObject json = ossHttpPostUtil(url, jsonData);        if(null!=json){            if (Integer.parseInt(json.get("errcode").toString()) == 0) {                String snsToken = json.getString("sns_token");                return snsToken;            }        }        return null;    }    public String getUnionId(String snsToken) {        String url = "https://oapi.dingtalk.com/sns/getuserinfo?sns_token="+snsToken;        JSONObject json = ossHttpGetUtil(url);        if(null!=json){            if (Integer.parseInt(json.get("errcode").toString()) == 0) {                JSONObject jsonUser = json.getJSONObject("user_info");                String unionid = jsonUser.getString("unionid");                return unionid;            }        }        return "";    }    public String getUserId(String accessToken, String unionId) {        String url = "https://oapi.dingtalk.com/user/getUseridByUnionid?unionid="+unionId+"&access_token="+accessToken;        JSONObject json = ossHttpGetUtil(url);        if(null!=json){            if (Integer.parseInt(json.get("errcode").toString()) == 0) {                String userId = json.getString("userid");                return userId;            }        }        return "";    }    public JSONObject getUserData(String accessToken, String userId) {        String url = "https://oapi.dingtalk.com/user/get?access_token="+accessToken+"&userid="+userId;        JSONObject json = ossHttpGetUtil(url);        if(null!=json){            if (Integer.parseInt(json.get("errcode").toString()) == 0) {                return json;            }        }        return null;    }    private JSONObject ossHttpGetUtil(String url){        HttpGet httpGet = new HttpGet(url);        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();        HttpClient httpClient = httpClientBuilder.build();        HttpResponse httpResponse = null;        try {            httpResponse = httpClient.execute(httpGet);        } catch (Exception e) {        }        BufferedReader bufferedReader = null;        StringBuilder entityStringBuilder = new StringBuilder();        //得到httpResponse的状态响应码        int statusCode = httpResponse.getStatusLine().getStatusCode();        JSONObject jsonObject = null;        String access_token = "";        if (statusCode == HttpStatus.SC_OK) {            //得到httpResponse的实体数据            HttpEntity httpEntity = httpResponse.getEntity();            if (httpEntity != null) {                try {                    return jsonObject = JSONObject.parseObject(EntityUtils.toString(httpEntity));                } catch (Exception e) {                }            }        }        return null;    }    private JSONObject ossHttpPostUtil(String url, JSONObject json){        HttpPost httpPost = new HttpPost(url);        HttpEntity httpEntity = null;        httpEntity = new StringEntity(json.toString(), "UTF-8");        httpPost.setEntity(httpEntity);        HttpResponse httpResponse = null;        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();        HttpClient httpClient = httpClientBuilder.build();        try {            httpResponse = httpClient.execute(httpPost);        } catch (Exception e) {        }        StringBuilder entityStringBuilder = new StringBuilder();        //得到httpResponse的状态响应码        int statusCode = httpResponse.getStatusLine().getStatusCode();        if (statusCode == HttpStatus.SC_OK) {            //得到httpResponse的实体数据            HttpEntity httpEntity2 = httpResponse.getEntity();            JSONObject jsonObject = null;            if (httpEntity2 != null) {                try {                    return jsonObject = jsonObject.parseObject(EntityUtils.toString(httpEntity2));                } catch (Exception e) {                }            }        }        return null;    }}


  • 第顶顶顶顶  
原创粉丝点击