diff --git a/api/.vscode/launch.json b/api/.vscode/launch.json index 382e513..50337d9 100644 --- a/api/.vscode/launch.json +++ b/api/.vscode/launch.json @@ -27,6 +27,7 @@ // 测试 "--apiEmisUrl http://10.8.30.161:1111", "--apiVcmpUrl http://localhost:4000", + "--apiIotAuth http://localhost:4200", "--godUrl https://restapi.amap.com/v3", "--godKey 21c2d970e1646bb9a795900dd00093ce", "--mqttVideoServer mqtt://10.8.30.71:30883", @@ -61,6 +62,8 @@ "--clickHouseDataAlarm default", "--confirmAlarmAnxinUserId 1", + "--vcmpAppId 5048b08d-c449-4d7f-b1ec-f741012aefe8", + "--vcmpAppSecret 5ba8c0ab-9fbd-4f07-9817-c48017c3cbad" ] }, { diff --git a/api/app/lib/controllers/alarm/video.js b/api/app/lib/controllers/alarm/video.js index 5d8dcfd..c1fac77 100644 --- a/api/app/lib/controllers/alarm/video.js +++ b/api/app/lib/controllers/alarm/video.js @@ -260,8 +260,27 @@ async function confirm (ctx) { } } +async function vcmpAppAuthToken (ctx) { + try { + const { models } = ctx.fs.dc; + const { utils: { vcmpAuth } } = ctx.app.fs + + const token = await vcmpAuth() + + ctx.status = 200; + ctx.body = { token } + } catch (error) { + ctx.fs.logger.error(`path: ${ctx.path}, error: error`); + ctx.status = 400; + ctx.body = { + message: typeof error == 'string' ? error : undefined + } + } +} + module.exports = { deviceType, alarmList, - confirm + confirm, + vcmpAppAuthToken }; \ No newline at end of file diff --git a/api/app/lib/routes/alarm/index.js b/api/app/lib/routes/alarm/index.js index 162e6c9..9cfcbdd 100644 --- a/api/app/lib/routes/alarm/index.js +++ b/api/app/lib/routes/alarm/index.js @@ -54,4 +54,7 @@ module.exports = function (app, router, opts) { app.fs.api.logAttr['PUT/alarm/video/confirm'] = { content: '确认视频告警信息', visible: true }; router.put('/alarm/video/confirm', videoAlarm.confirm); + + app.fs.api.logAttr['GET/vcmp/auth'] = { content: '获取视频平台应用鉴权token', visible: true }; + router.get('/vcmp/auth', videoAlarm.vcmpAppAuthToken); }; diff --git a/api/app/lib/utils/vcmpAuth.js b/api/app/lib/utils/vcmpAuth.js new file mode 100644 index 0000000..f8b0c2a --- /dev/null +++ b/api/app/lib/utils/vcmpAuth.js @@ -0,0 +1,30 @@ +'use strict'; +const moment = require('moment') + +module.exports = function (app, opts) { + + async function vcmpAuth () { + const { vcmp: { app: vcApp } } = opts + const vcmpAuth = await app.redis.hgetall('vcmpAuth'); + if (vcmpAuth.token && moment().isBefore(moment(vcmpAuth.expires))) { + return vcmpAuth.token + } else { + let res = await app.fs.iotAuthRequest.post('oauth2/token', { + data: { + grant_type: 'client_credentials' + }, + header: { + Authorization: `Basic ${Buffer.from(`${encodeURIComponent(vcApp.id)}:${encodeURIComponent(vcApp.secret)}`).toString('base64')}` + } + }) + await app.redis.hmset('vcmpAuth', { + ...res + }); + return res.token + } + } + + return { + vcmpAuth + } +} \ No newline at end of file diff --git a/api/config.js b/api/config.js index 7707bff..83caaf4 100644 --- a/api/config.js +++ b/api/config.js @@ -20,6 +20,7 @@ args.option('redisPswd', 'redisPassword'); args.option('axyApiUrl', '安心云 api'); args.option('apiEmisUrl', '企业管理 api'); args.option('apiVcmpUrl', '视频平台 api'); +args.option('apiIotAuth', 'IOT 鉴权平台') args.option('godUrl', '高德地图API请求地址'); args.option('godKey', '高德地图API key'); @@ -43,6 +44,10 @@ args.option('clickHouseDataAlarm', 'clickHouse 视频平台数据告警库名称 args.option('confirmAlarmAnxinUserId', '确认告警时保存到 ES 的安心云的用户的 id'); +// 视频应用秘钥 +args.option('vcmpAppId', '视频平台 应用 id') +args.option('vcmpAppSecret', '视频平台 应用秘钥') + const flags = args.parse(process.argv); const POMS_DB = process.env.POMS_DB || flags.pg; @@ -62,6 +67,8 @@ const API_ANXINYUN_URL = process.env.API_ANXINYUN_URL || flags.axyApiUrl; const API_EMIS_URL = process.env.API_EMIS_URL || flags.apiEmisUrl; // 视频平台 api const API_VCMP_URL = process.env.API_VCMP_URL || flags.apiVcmpUrl; +// iot鉴权平台 api +const API_IOT_AUTH = process.env.API_IOT_AUTH || flags.apiIotAuth; // 高德地图的参数 const GOD_URL = process.env.GOD_URL || flags.godUrl || 'https://restapi.amap.com/v3'; @@ -91,6 +98,10 @@ const CONFIRM_ALARM_ANXIN_USER_ID = process.env.CONFIRM_ALARM_ANXIN_USER_ID || f const PLATFORM_NAME = process.env.PLATFORM_NAME || flags.platformName || 'anxinyun'; +// 视频平台应用秘钥 +const VCMP_APP_ID = process.env.VCMP_APP_ID || flags.vcmpAppId +const VCMP_APP_SECRET = process.env.VCMP_APP_SECRET || flags.vcmpAppSecret + if ( !POMS_DB || !IOTA_REDIS_SERVER_HOST || !IOTA_REDIS_SERVER_PORT @@ -99,10 +110,12 @@ if ( || !API_ANXINYUN_URL || !API_EMIS_URL || !API_VCMP_URL + || !API_IOT_AUTH || !QINIU_DOMAIN_QNDMN_RESOURCE || !QINIU_BUCKET_RESOURCE || !QINIU_AK || !QINIU_SK || !CLICKHOUST_URL || !CLICKHOUST_PORT || !CLICKHOUST_ANXINCLOUD || !CLICKHOUST_PEP_EMIS || !CLICKHOUST_PROJECT_MANAGE || !CLICKHOUST_VCMP || !CLICKHOUST_DATA_ALARM || !CONFIRM_ALARM_ANXIN_USER_ID + || !VCMP_APP_ID || !VCMP_APP_SECRET ) { console.log('缺少启动参数,异常退出'); args.showHelp(); @@ -137,6 +150,12 @@ const product = { anxinCloud: { confirmAlarmAnxinUserId: CONFIRM_ALARM_ANXIN_USER_ID }, + vcmp: { + app: { + id: VCMP_APP_ID, + secret: VCMP_APP_SECRET + } + }, kafka: { rootURL: ANXINCLOUD_KAFKA_BROKERS, topicPrefix: PLATFORM_NAME @@ -173,6 +192,9 @@ const product = { }, { name: 'vcmpRequest', root: API_VCMP_URL + }, { + name: 'iotAuthRequest', + root: API_IOT_AUTH }, { name: 'godRequest', root: GOD_URL,