openid 钉钉_钉钉开发入门,微应用识别用户身份,获取用户免登授权码code,获取用户userid,获取用户详细信息...

最近有个需求,在钉钉内,点击微应用,获取用户身份,根据获取到的用户身份去企业内部的用户中心做校验,校验通过,相关子系统直接登陆;

就是在获取这个用户身份的时候,网上的资料七零八落的,找的人烦躁的很,所以自己记录一下;

实现这个要求,有好几种方式,使用ISV方式相对来说比较简单一点,获取的到的信息虽然没有其他方式那么全,但是也包含了百分之七八十的信息,少了角色信息之类的;

效果:(demo的GIT地址在文末)

20180511192632550642.png

20180511192632909054.png

说说步骤:

20180511192633379776.png

这个首页跳转地址,信任了以后,就可以直接使用js-sdk来获取用户code等相关信息,最方便的一种.

如果是别的页面,使用js-sdk 需要进行dd.config的初始化,这个初始化里面,包含了相关的权限校验.

2.应用创建完了以后,会生成一个agentID,

如果仅仅只是为了获取当前点击用户的信息,并且获取的位置是在这个首页地址的js里面,则大可以不用管这个信息,但是,如果需要更加复杂的操作,就需要获取这个ID,获取方法在创建完了以后,右上角的小三角下拉,有个设置,点进去就能看到

另外,关于js-sdk的需要鉴权的api信息查询地址:jsapi列表(是否需要dd.config校验)

列表里面不需要的接口调用,都不需要进行dd.config()

3.获取钉钉开发的corpID和corpSecert

20180511192633508687.png

一般获取上面的足够.web sso免登可能需要下面的SSOSecert;

4.准备工作做完

现在我们有以下信息:

corpID:

corpSecert:

agentID:

url:这个url就是你需要获取用户code的那个页面url

当然如果只是简单的获取用户信息,不需要进行dd.config的话,可以不用管agrntID和url

5.进入开发(这里只是做获取当前用户信息的示例)

(1).前端页面引入dingtalk.js

(2).在页面添加 获取code 的 js 代码,

(3).将获取的 code发送到后台处理

后台根据上一步返回的简单的,包含userid的信息,拿到userid

(5).返回给前台显示,或者进行后续开发

贴一贴这个流程中关键一点的代码:

前端页面在引入js 后,或有一个dd的全局变量,这个就是js-sdk,如果需要权限校验的,就要放在最前边

dd.ready(function() {

dd.runtime.permission.requestAuthCode({

corpId :"这里是你的corpID",

onSuccess :function(result) {var code =result.code;

alert(code);

//将code 发往后台处理

},

onFail :function(err) {

alert(‘出错了, ‘ +err);

}

});

});

后台处理部分:

AuthHelper.java 文末提供

在接收到授权码以后:

String accessToken =AuthHelper.getAccessToken(CORP_ID, CORP_SECRET);

String user= AuthHelper.getUserInfo(code, accessToken);

当返回正确的时候,这个user 里面结果大致是这样的:

{"errcode": 0,"errmsg": "ok","userid": "USERID","deviceId":"DEVICEID","is_sys": true,"sys_level": 0|1|2}

然后根据里面的userid,获取详细的用户信息:

String userall = AuthHelper.getUser(userid, accessToken);

返货正确的话,这个userall里面的结果大致是:(具体查看钉钉开发文档)

{"errcode": 0,"unionid": "PiiiPyQqBNBii0HnCJ3zljcuAiEiE","openId": "PiiiPyQqBNBii0HnCJ3zljcuAiEiE","roles": [{"id": 23003585,"name": "财务","groupName": "职务"}],"remark": "备注","userid": "04232334556237185","isLeaderInDepts": "{1:false}","isBoss": false,"hiredDate": 1520265600000,"isSenior": false,"tel": "010-88996533","department": [1,2],"workPlace": "北京市朝阳区","email": "ceshi@aliyun.com","orderInDepts": "{1:71738366882504}","dingId": "$:LWCP_v1:$aTPvVHhhsCMtDZRQ1xbYGg==","mobile": "15901516821","errmsg": "ok","active": false,"avatar": "dingtalk.com/abc.jpg","isAdmin": false,"isHide": false,"jobnumber": "001","name": "测试名字","extattr": {},"stateCode": "86","position": "总监"}

然后简单的获取信息到此结束;

注意的是:

如果需要更多的操作,就需要在前端页面进行dd.config的初始化,这个里面的所需要的sign,可以在后台根据相关信息生成,是必不可少的,生成规则见AuthHelper.java(其他工具类见文末的 git 地址)

importjava.io.IOException;importjava.io.UnsupportedEncodingException;importjava.security.MessageDigest;importjava.security.NoSuchAlgorithmException;importjava.util.Formatter;importcn.jlhd.util.HttpHelper;importcn.jlhd.util.JsonUtil;importcn.jlhd.util.ReturnUtil;/***

* 1.获取accessToken

* 2.获取jsapi中的ticket

* 3.生成jsapiz中的鉴权sign

* 4.根据传入的临时code获取用户的基本信息,入userinfo

* 5.根据userid获取详细用户信息

*

*@authorlnexin

**/

public classAuthHelper {//钉钉api相关

static String TOKEN_URL = "https://oapi.dingtalk.com/gettoken";static String TICKET_URL = "https://oapi.dingtalk.com/get_jsapi_ticket";static String USER_INFO_URL = "https://oapi.dingtalk.com/user/getuserinfo";static String USER_ALL_URL = "https://oapi.dingtalk.com/user/get";//调整到1小时50分钟

public static final long cacheTime = 1000 * 60 * 55 * 2;private static String ACCESS_TOKEN = null;private static String JSAPI_TICKET = null;private static long LAST_TIME = 0;/***

*@paramcorpId

*@paramcorpSecert

*@return与钉钉服务器请求生成的accessToken*/

public staticString getAccessToken(String corpId, String corpSecert) {long curTime =System.currentTimeMillis();long differ = curTime -LAST_TIME;if (ACCESS_TOKEN != null && differ

ACCESS_TOKEN=requestAccessToken(corpId, corpSecert);

LAST_TIME=curTime;returnACCESS_TOKEN;

}/***

*@paramaccessToken

*

*@seegetAccess_Token(String corpId, String corpSecert) 生成的access_token

*@return一个用于js鉴权的ticket*/

public staticString getJsapiTicket(String accessToken) {long curTime =System.currentTimeMillis();long differ = curTime -LAST_TIME;if (JSAPI_TICKET != null && differ

}

JSAPI_TICKET=requestJsapiTicket(accessToken);returnJSAPI_TICKET;

}/*** 根据传入的相关参数生成sign

*

*@paramticket

*@paramnonceStr

*@paramtimeStamp

*@paramurl

*@return

*/

public static String sign(String ticket, String nonceStr, longtimeStamp, String url) {

StringBuffer plain= newStringBuffer();

plain.append("jsapi_ticket=").append(ticket);

plain.append("&noncestr=").append(nonceStr);

plain.append("&timestamp=").append(String.valueOf(timeStamp));

plain.append("&url=").append(url);

MessageDigest sha;try{

sha= MessageDigest.getInstance("SHA-1");

sha.reset();

sha.update(plain.toString().getBytes("UTF-8"));returnbytesToHex(sha.digest());

}catch(NoSuchAlgorithmException e) {

e.printStackTrace();

}catch(UnsupportedEncodingException e) {

e.printStackTrace();

}return null;

}private staticString requestAccessToken(String corpId, String corpSecert) {

StringBuffer url= newStringBuffer(TOKEN_URL);

url.append("?corpid=").append(corpId);

url.append("&corpsecret=").append(corpSecert);

String result= null;try{

result=HttpHelper.sendGet(url.toString());

}catch(IOException e) {

result= ReturnUtil.result("-1","请求accessTokenc出错!corpid:" + corpId + ",corpsecert:" + corpSecert + "异常信息:" +e);

}

return JsonUtil.getJsonNode(result).get("access_token").asText();

}private staticString requestJsapiTicket(String accessToken) {

StringBuffer url= newStringBuffer(TICKET_URL);

url.append("?access_token=").append(accessToken);

String result= null;try{

result=HttpHelper.sendGet(url.toString());

}catch(IOException e) {

result= ReturnUtil.result("-1", "请求JsapiTicket出错!accessToken:" + accessToken + "异常信息:" +e);

}

return JsonUtil.getJsonNode(result).get("ticket").asText();

}private static String bytesToHex(byte[] hash) {

Formatter formatter= newFormatter();for (byteb : hash) {

formatter.format("%02x", b);

}

String result=formatter.toString();

formatter.close();returnresult;

}/*** 获取用户信息

*

*@paramcode

* 用户相应的临时code

*@paramtoken

* 根据相应corpid和corpsecret生成的access_token

*@return用户ID等相关信息*/

public staticString getUserInfo(String code, String accessToken) {

StringBuffer url= newStringBuffer(USER_INFO_URL);

url.append("?access_token=").append(accessToken);

url.append("&code=").append(code);

String result= null;try{

result=HttpHelper.sendGet(url.toString());

}catch(IOException e) {

result= ReturnUtil.result("-1", "请求User信息出错!code:" + code + "异常信息:" +e);

}returnresult;

}/*** 获取用户详细信息

*@paramuserid 在某个corpid下的唯一用户userid

*@paramaccessToken 据相应corpid和corpsecret生成的access_token

*@return

*/

public staticString getUser(String userid, String accessToken) {

StringBuffer url= newStringBuffer(USER_ALL_URL);

url.append("?access_token=").append(accessToken);

url.append("&userid=").append(userid);

String result= null;try{

result=HttpHelper.sendGet(url.toString());

}catch(IOException e) {

result= ReturnUtil.result("-1", "请求User信息出错!userid:" + userid + "异常信息:" +e);

}returnresult;

}

}

做了一个简单demo获取用户信息:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/287674.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

趣味二维码生成

1背景介绍 最近在 Github 看到了一个有趣的项目 amazing-qr,它支持生成普通二维码,带图片的艺术二维码,动态二维码。项目是用 python 编写的,以命令行的方式运行生成,不太方便调用,因此,我…

《零基础看得懂的C++入门教程 》——(1)第一个C++程序就让你知其所以然

一、学习目标 了解第一个C程序了解第一个C程序结构了解什么是注释了解什么是命名空间了解C语言的输出(如何在程序运行时显示内容)了解语句结束后需要使用什么符号表示结束 了解程序入口 目录 预备第一篇,使用软件介绍在这一篇,…

1、Locust压力测试环境搭建

环境准备:阿里云服务器一台、python2.7、pip Locust 介绍Locust 是一个开源负载测试工具。使用 Python 代码定义用户行为,也可以仿真百万个用户。 Locust 简单易用,分布式,用户负载测试工具。Locust 主要为网站或者其他系统进行负…

交互式 .Net

1名词解析 1. 交互式交互式是指输入代码后可直接运行该代码,然后持续输入运行代码。2. 交互式 .Net.Net 是一种编译型语言,不像 python 这类的脚本型语言,可以边输入代码边运行结果。幸运的是,软微推出了 interactive 这个项…

mysql signed 长度_浅谈mysql字段长度设置

mysql 中最常用的数据类型是tinyint,smallint,int,bigint,char,varchar;char(n)和varchar(n)存储固定长度的字符数据,长度最大为254字节。使用 ‘n’字节的存储空间;有符号和无符号区别:有符号可以存储负值,无符号只能存储0和非负值数值;tinyint 占用1字节的存储空间…

R语言-异常数据处理2

在R中进行基于稳健马氏距离的异常检验 前言 我们研究的数据中经常包含着一些不同寻常的样本,这称之为异常值(Outlier)。这些异常值会极大的影响回归或分类的效果。异常值产生的原因有很多,其中可能是人为错误、数据测量误差,或者是实际确实存…

《零基础看得懂的C++入门教程 》——(2)什么是数据类型、变量?一看便会

一、学习目标 了解基本常用的数据类型了解什么是变量 目录 预备第一篇,使用软件介绍在这一篇,C与C使用的软件是一样的,查看这篇即可:《软件介绍》 想了解编译原理和学习方法点这篇,学习方法和一些原理C与C都是相同的…

pycharm 快捷键介绍

CtrlN (Navigate | Class) 打开输入框输入要查找的类名 Ctrl空格 代码自动补全 Ctrl空格(按两次)对于没有导入的类自动完成导入代码并自动补全 AltF7 查找方法变量在工程中的所有应用 CtrlQ (View | Quick Documentation). 快速查看文档 …

db2和mysql语句区别_db2和mysql语法的区别是什么

MySQL默认使用大小写敏感的数据库名、表名和列名(可以通过lower_case_table_names参数控制是否大小写敏感),DB2数据库对大小写不敏感。虽然MySQL与DB2都遵循并符合SQL92标准且大多数SQL相互兼容,但是在一些细节的实现上有一些不同的地方。比如&#xff1…

查缺补漏系统学习 EF Core 6 - 数据查询

这是 EF Core 系列的第四篇文章,上一篇文章讲述了 EF Core 中的实体迁移与数据播种。这篇文章盘点一下 EF Core 的几种数据查询方式,内容较多分上下两篇。点击上方或后方蓝字,阅读 EF Core 系列合集。简单查询在 EF Core 中,每个查…

《零基础看得懂的C++入门教程 》——(3)表达式花样挺多鸭

一、学习目标 了解变量之间的计算了解什么是表达式了解什么是自增、自减 目录 预备第一篇,使用软件介绍在这一篇,C与C使用的软件是一样的,查看这篇即可:《软件介绍》 想了解编译原理和学习方法点这篇,学习方法和一些…

prometheus python client

为什么80%的码农都做不了架构师?>>> 当我刚开始准备使用Python写一个promethues的client的时候,并没有想到过程这么麻烦。github上的大佬们也没兴趣帮我解决这些细节的问题。以下是我在使用prometheus_client遇到的一些问题,仅供…

【遥感数字图像处理】实验:遥感影像分类(监督、非监督分类)完整流程(Erdas版)

一.实验目的: 理解计算机图像分类的基本原理,掌握数字图像非监督分类以及监督分类的具体方法和过程,以及两种分类方法的区别。 二.实验平台:ERDAS IMAGINE 9.1 三.实验要求:掌握非监督分类;非监督分类结果评价;监督分类;监督分类结果评价;分类后处理。 四.实验…

重大跨越!Windows 11 23H2 25115 推送:2023 年更新测试开启,水印回归

面向 Dev 频道的 Windows 预览体验成员,微软现已发布 Windows 11 预览版 Build 25115。主要变化1.微软宣布从 Dev 频道切换到 Beta 频道的选项正式关闭,Beta 频道将继续测试 Windows 11 版本 22H2,而 Dev 频道将开启 2023 年更新 Windows 11 …

《零基础看得懂的C++入门教程 》——(4)条件判断原来如此

一、学习目标 了解什么是条件判断了解多个条件判断了解输入了解什么是逻辑与、逻辑或 目录 预备第一篇,使用软件介绍在这一篇,C与C使用的软件是一样的,查看这篇即可:《软件介绍》 想了解编译原理和学习方法点这篇,学…

Django学习笔记(4)

为什么80%的码农都做不了架构师?>>> 首先提一个问题:在Django中如何处理CRSF(Cross-site request forgery)? 先看一下CSRF原理。 其实就是恶意网站利用正常网站的cookie去非法请求。 ##Java处理方式## 一般做法需要后台和前端配合采取策略去…

.NET版OCR紧随PP-OCRv3重磅发布

.net版OCR地址PaddleOCRSharp:https://gitee.com/raoyutian/paddle-ocrsharpPaddleOCRSharp是一个基于PaddleOCR的C代码修改并封装的.NET的工具类库。包含文本识别、文本检测、基于文本检测结果的统计分析的表格识别功能,同时针对小图识别不准的情况下&a…

《零基础看得懂的C++入门教程 》——(5) 容我套个娃 循环

一、学习目标 了解循环的使用方法 目录 预备第一篇,使用软件介绍在这一篇,C与C使用的软件是一样的,查看这篇即可:《软件介绍》 想了解编译原理和学习方法点这篇,学习方法和一些原理C与C都是相同的《脱离学习误区》 …

Android两个注意事项.深入了解Intent和IntentFilter(两)

深入理解Intent和IntentFiler(二)转载请表明出处:http://blog.csdn.net/u012637501(嵌入式_小J的天空) 在上一篇文章中,我们比較具体学习了"Intent"的相关知识,如今将学习怎样设置Intent对象的这些属性以及怎样使用他们来启动组件。…

Oracle常用sql语句(一)

Sql的分类DDL操作数据库表列等表基本的操作主键索引视图 常用数据类型字符串类型数字类型日期类型LOB类型LONG类型 数据转换character datenumbercharacter通用函数条件表达式Sql的分类 DDL (Data Definition Language):数据定义语言&#xf…