Angular 应用授权和 Zoho CRM 的问题
Posted
技术标签:
【中文标题】Angular 应用授权和 Zoho CRM 的问题【英文标题】:Issue with Angular App Authorization and Zoho CRM 【发布时间】:2022-01-15 00:47:07 【问题描述】:我正在寻找一种方法来构建一个 Angular 应用程序,该应用程序可以发送请求并接收来自 Zoho CRM 的响应。我尝试了 Zoho CRM 文档中记录的所有可能性,但对我没有任何帮助:
我遵循的步骤:
我在https://api-console.zoho.com/ 上注册了应用程序,为基于客户端、基于服务器、自客户端。
我按照文档https://www.zoho.com/accounts/protocol/oauth/web-server-applications.html 处理每种情况(客户端、服务器、自身)。
请求授权请求以获取代码并生成令牌以访问 CRM API https://accounts.zoho.com/oauth/v2/auth?response_type=code&client_id=1000.GMB0YULZHJK411284S8I5GZ4CHUEX0&scope=AaaServer.profile.Read&redirect_uri=https://www.zylker.com/oauthredirect&prompt=consent
我在重定向的 URL 中获得了代码https://www.zylker.com/oauthredirect?code=1000.9c3a2a6a5362125efc9f7666224313b6.d44f4b5b63e71fc682cdf20c771efead&location=us
从应用程序生成令牌失败,即使在使用上面 URL 中生成的代码从邮递员那里获取令牌之后,任何请求也是如此。
并且总是遇到 CORS 政策问题,即使我在请求标头中添加了 "Access-Control-Allow-Origin":"*"
或将 *
替换为我的来源:
【问题讨论】:
【参考方案1】:运行您的项目,您应该被重定向到 zoho 以授予您访问权限。
您还应该被重定向到您在 zoho 控制台中设置的重定向 URL,请添加以下内容以将参数保存到您的本地存储,redirect.component.ts:
import Component, OnInit from '@angular/core';
@Component(
selector: 'app-redirect',
templateUrl: './redirect.component.html',
styleUrls: ['./redirect.component.css']
)
export class RedirectComponent implements OnInit
constructor()
ngOnInit(): void
this.setAccessToken();
getPropertiesFromURL()
var props: any = ;
var propertyString = window.location.hash || window.location.search;
if (propertyString && typeof propertyString === 'string')
propertyString = propertyString.slice(1);
if (propertyString)
propertyString
.split('&')
.forEach(function (prop)
var key = prop.split('=')[0], value = prop.split('=')[1];
props[key] = value;
);
return props;
// set the access token and grant access to localstorage
setAccessToken()
var hashProps = this.getPropertiesFromURL();
console.log("hashprops", hashProps)
if (hashProps)
for (var k in hashProps)
if (hashProps.hasOwnProperty(k))
var key = (k === 'access_toke' || k === 'access_token') ? 'access_token' : k;
var value = (k === 'api_domain') ? decodeURIComponent(hashProps[k]) : hashProps[k];
localStorage.setItem(key, value);
setTimeout(function () window.close(); , 0);
-
现在您可以在 app.component.ts 处添加以下内容以获得响应:
var input = 'module' : 'Leads';
ZCRM.API.RECORDS.get(input).then(function(resp)
var data = JSON.parse(resp).data;
console.log("data", data)
);
-
在第 3 点我已经在 377 到 387 行和 84 行稍微修改了 SDK 以适应我的情况它应该也适合您,我将发布原始 SDK,您也可以对其进行配置。
原始 SDK:
var libBase, headers, HTTP_METHODS, version;
version = 2;
HTTP_METHODS =
GET : "GET",//No I18N
POST : "POST",//No I18N
PUT : "PUT",//No I18N
DELETE : "DELETE"//No I18N
;
function promiseResponse(request)
return new Promise(function (resolve, reject)
var body, baseUrl, xhr, i, formData;
libBase = localStorage.api_domain+"/crm/v"+version+"/";
baseUrl = libBase + request.url;
var token = ZCRM.API.AUTH.getAccess();
if(token == null)
return resolve(''); // in case of no ticket, returns empty json
if (request.params)
baseUrl = baseUrl + '?' + request.params;
xhr = new XMLHttpRequest();
xhr.withCredentials = true
xhr.open(request.type, baseUrl);
xhr.setRequestHeader("Authorization", "Zoho-oauthtoken "+token)
for (i in headers)
xhr.setRequestHeader(i, headers[i]);
if (request.download_file)
xhr.responseType = "blob";//No I18N
if (request.x_file_content)
formData = new FormData();
formData.append('file', request.x_file_content);//No I18N
xhr.send(formData);
else
body = request.body || null;
xhr.send(body);
xhr.onreadystatechange = function()
if(xhr.readyState == 4)
if (xhr.status == 204)
var respObj =
"message" : "no data", //No I18N
"status_code" : "204" //No I18N
resolve(JSON.stringify(respObj));
else
if (request.download_file)
var filename;
var disposition = xhr.getResponseHeader("Content-Disposition");//No I18N
if (disposition && disposition.indexOf('attachment') !== -1)
var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
var matches = filenameRegex.exec(disposition);
if (matches != null && matches[1])
filename = matches[1].replace(/['"]/g, '');
filename = filename.replace('UTF-8','');
var blob = xhr.response;
var url = URL.createObjectURL(blob);
var ttt = document.createElement('a');
ttt.href = url;
ttt.download = filename;
ttt.click();
else
resolve(xhr.response);
)
;
function createParams(parameters)
var params, key;
for (key in parameters)
if (parameters.hasOwnProperty(key))
if (params)
params = params + key + '=' + parameters[key] + '&';
else
params = key + '=' + parameters[key] + '&';
return params;
;
function constructRequestDetails(input, url, type, isModuleParam)
var requestDetails = ;
requestDetails.type = type;
if (input != undefined)
if (input.id)
url = url.replace("id", input.id);
// url = url + "/" + input.id;
else
url = url.replace("/id", "");
if (input.params)
requestDetails.params = createParams(input.params) + (input.module && isModuleParam ? "module=" + input.module : "");//No I18N
if (!requestDetails.params && isModuleParam)
requestDetails.params = "module=" + input.module;//No I18N
if (input.body && (type == HTTP_METHODS.POST || type == HTTP_METHODS.PUT))
requestDetails.body = JSON.stringify(input.body);
if (input.x_file_content)
requestDetails.x_file_content = input.x_file_content;
if (input.download_file)
requestDetails.download_file = input.download_file;
requestDetails.url = url;
return requestDetails;
;
function getParameterByName(name, url)
if (!url) url = window.location.href;
name = name.replace(/[\[\]]/g, "\\$&");
var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)");
var results = regex.exec(url);
if (!results) return null;
if (!results[2]) return '';
return decodeURIComponent(results[2].replace(/\+/g, " "));
function sdk()
return
initialize : function (configuration)
if(document.getElementById("zes_client_scope") == null)
var elem = document.createElement('div');
elem.setAttribute("data-scope",configuration.scopes);
elem.setAttribute("data-clientid",configuration.client_id);
elem.setAttribute("data-accounts-url",configuration.accounts_url);
elem.setAttribute("id","zes_client_scope");
document.body.appendChild(elem);
var input = ;
ZCRM.API.USERS.get(input).then(function(resp)
);
function actions()
return
convert : function (input)
return promiseResponse(constructRequestDetails(input, "Leads/id/actions/convert", HTTP_METHODS.POST, false));//No I18N
function attachments()
return
uploadFile : function (input)
return promiseResponse(constructRequestDetails(input, input.module+ "/id/Attachments", HTTP_METHODS.POST, false));//No I18N
,
deleteFile : function (input)
return promiseResponse(constructRequestDetails(input, input.module+ "/id/Attachments/"+input.relatedId, HTTP_METHODS.DELETE, false));//No I18N
,
downloadFile : function (input)
input.download_file = true;
return promiseResponse(constructRequestDetails(input, input.module+ "/id/Attachments/"+input.relatedId, HTTP_METHODS.GET, false));//No I18N
,
uploadLink : function (input)
return promiseResponse(constructRequestDetails(input, input.module+ "/id/Attachments", HTTP_METHODS.POST, false));//No I18N
,
uploadPhoto : function (input)
return promiseResponse(constructRequestDetails(input, input.module+ "/id/photo", HTTP_METHODS.POST, false));//No I18N
,
downloadPhoto : function (input)
input.download_file = true;
return promiseResponse(constructRequestDetails(input, input.module + "/id/photo", HTTP_METHODS.GET, false));//No I18N
,
deletePhoto : function (input)
return promiseResponse(constructRequestDetails(input, input.module + "/id/photo", HTTP_METHODS.DELETE, false));//No I18N
function org()
return
get : function (input)
return promiseResponse(constructRequestDetails(input, "org", HTTP_METHODS.GET, true));//No I18N
function records()
return
get : function(input)
return promiseResponse(constructRequestDetails(input, input.module + "/id", HTTP_METHODS.GET, false));//No I18N
,
post : function(input)
return promiseResponse(constructRequestDetails(input, input.module + "/id", HTTP_METHODS.POST, false));//No I18N
,
put : function(input)
return promiseResponse(constructRequestDetails(input, input.module + "/id", HTTP_METHODS.PUT, false));//No I18N
,
delete : function (input)
return promiseResponse(constructRequestDetails(input, input.module + "/id", HTTP_METHODS.DELETE, false));//No I18N
,
getNotes : function (input)
return promiseResponse(constructRequestDetails(input, input.module + "/id/Notes", HTTP_METHODS.GET, false));//No I18N
,
getRelated : function (input)
return promiseResponse(constructRequestDetails(input, input.module + "/id/"+input.relatedModule, HTTP_METHODS.GET, false));//No I18N
,
getAllDeletedRecords : function (input)
if (input.params)
input.params.type = "all";
else
input.params =
"type" : "all"//No I18N
;
return promiseResponse(constructRequestDetails(input, input.module + "/deleted", HTTP_METHODS.GET, false));//No I18N
,
getRecycleBinRecords : function (input)
if (input.params)
input.type = "recycle";
else
input.params =
"type" : "recycle"//No I18N
;
return promiseResponse(constructRequestDetails(input, input.module + "/deleted", HTTP_METHODS.GET, false));//No I18N
,
getPermanentlyDeletedRecords : function (input)
if (input.params)
input.type = "permanent";
else
input.params =
"type" : "permanent"//No I18N
;
return promiseResponse(constructRequestDetails(input, input.module + "/deleted", HTTP_METHODS.GET, false));//No I18N
,
search : function (input)
return promiseResponse(constructRequestDetails(input, input.module + "/search", HTTP_METHODS.GET, false));//No I18N
function settings()
return
getFields : function (input)
return promiseResponse(constructRequestDetails(input, "settings/fields/id", HTTP_METHODS.GET, true));//No I18N
,
getLayouts : function (input)
return promiseResponse(constructRequestDetails(input, "settings/layouts/id", HTTP_METHODS.GET, true));//No I18N
,
getCustomViews : function (input)
return promiseResponse(constructRequestDetails(input, "settings/custom_views/id", HTTP_METHODS.GET, true));//No I18N
,
updateCustomViews : function (input)
return promiseResponse(constructRequestDetails(input, "settings/custom_views/id", HTTP_METHODS.PUT, true));//No I18N
,
getModules : function (input)
return promiseResponse(constructRequestDetails(input, "settings/modules" + ((input && input.module) ? "/" + input.module : ""), HTTP_METHODS.GET, false));//No I18N
,
getRoles : function (input)
return promiseResponse(constructRequestDetails(input, "settings/roles/id", HTTP_METHODS.GET, true));//No I18N
,
getProfiles : function (input)
return promiseResponse(constructRequestDetails(input, "settings/profiles/id", HTTP_METHODS.GET, true));//No I18N
,
getRelatedLists : function (input)
return promiseResponse(constructRequestDetails(input, "settings/related_lists/id", HTTP_METHODS.GET, true));//No I18N
function users()
return
get : function (input)
return promiseResponse(constructRequestDetails(input, "users/id", HTTP_METHODS.GET, true));//No I18N
var listener = 0;
function auth()
return
getAccess : function()
if(listener == 0)
window.addEventListener("storage", function(e)
if(e.key === 'access_token' && e.oldValue!=e.newValue && e.oldValue == null)
location.reload();
if(e.key === 'access_token')
localStorage.removeItem('__auth_process');
, false);
listener = 1;
if(localStorage.getItem('__auth_process')) localStorage.removeItem('__auth_process');
var valueInStore = localStorage.getItem('access_token');
var token_init = localStorage.getItem('__token_init');
if(token_init != null && valueInStore != null && Date.now() >= parseInt(token_init)+55*60*1000) // check after 55 mins
valueInStore = null;
localStorage.removeItem('access_token');
var auth_process = localStorage.getItem('__auth_process');
if (valueInStore == null && auth_process == null)
var accountsUrl =document.getElementById("zes_client_scope").getAttribute("data-accounts-url");
var endPoint = "/oauth/v2/auth";
var full_grant = localStorage.getItem('full_grant');
if(full_grant != null && 'true' == full_grant && localStorage.getItem('__token_init') != null)
endPoint += '/refresh';
var client_id = document.getElementById("zes_client_scope").getAttribute("data-clientid");
var scope = document.getElementById("zes_client_scope").getAttribute("data-scope");
var path = window.location.pathname;
var redirect_url = window.location.origin;
var pathSplit = path.split('/');
var length=pathSplit.length
for (var i=0;i<length-2;i++)
redirect_url +=pathSplit[i]+"/";
if(location.hostname=="127.0.0.1" ||location.hostname=="localhost" ||location.hostname=="" )
if(length-2 == 0)
redirect_url += "/";
redirect_url += "app/"
redirect_url = redirect_url + "redirect.html";
if (client_id && scope)
localStorage.setItem('__token_init', Date.now());
localStorage.removeItem('access_token');
localStorage.setItem('__auth_process', 'true');
var popup = window.open(accountsUrl+endPoint+"?scope="+scope+"&client_id="+client_id+"&response_type=token&state=zohocrmclient&redirect_uri="+redirect_url);//,'', 'width:' + window.innerWidth + ',height:' + window.innerHeight);
//popup.focus();
else
throw 'missing auth params[clientId, redirectUri, scope]';
return valueInStore;
,
revokeAccess : function ()
localStorage.removeItem('crm_access_token');
var ZCRM = (function (argument)
return
API : (function (argument)
return
SDK : new sdk(),
AUTH : new auth(),
RECORDS : new records(),
SETTINGS : new settings(),
ACTIONS : new actions(),
USERS : new users(),
ORG : new org(),
ATTACHMENTS : new attachments()
)(this),
init: function(data)
if(data.constructor === .constructor && data.hasOwnProperty('full_grant') && data['full_grant'] == true)
localStorage.setItem('full_grant', 'true');
)(this)
我希望这能让别人的生活更轻松,如果有任何机构有更好的解决方案,我很乐意检查一下
【讨论】:
【参考方案2】:-
在https://api-console.zoho.com/ 上注册您的应用,作为基于客户端的应用
-
在您的 Angular 应用程序中,创建一个 RedirectComponent 并将其包含在您的 app-routing.module.ts 中
-
在您的资产中创建 zcrmsdk.js 并输入以下代码:
var libBase, headers, HTTP_METHODS, version;
version = 2;
HTTP_METHODS =
GET: "GET",//No I18N
POST: "POST",//No I18N
PUT: "PUT",//No I18N
DELETE: "DELETE"//No I18N
;
function promiseResponse(request)
return new Promise(function (resolve, reject)
var body, baseUrl, xhr, i, formData;
libBase = localStorage.api_domain + "/crm/v" + version + "/";
// console.log("libbase", libBase)
baseUrl = libBase + request.url;
var token = ZCRM.API.AUTH.getAccess();
if (token == null)
return resolve(''); // in case of no ticket, returns empty json
if (request.params)
baseUrl = baseUrl + '?' + request.params;
xhr = new XMLHttpRequest();
xhr.withCredentials = true
xhr.open(request.type, baseUrl);
xhr.setRequestHeader("Authorization", "Zoho-oauthtoken " + token)
for (i in headers)
xhr.setRequestHeader(i, headers[i]);
if (request.download_file)
xhr.responseType = "blob";//No I18N
if (request.x_file_content)
formData = new FormData();
formData.append('file', request.x_file_content);//No I18N
xhr.send(formData);
else
body = request.body || null;
xhr.send(body);
xhr.onreadystatechange = function ()
if (xhr.readyState == 4)
if (xhr.status == 204)
var respObj =
"message": "no data", //No I18N
"status_code": "204" //No I18N
resolve(JSON.stringify(respObj));
else
if (request.download_file)
var filename;
var disposition = xhr.getResponseHeader("Content-Disposition");//No I18N
if (disposition && disposition.indexOf('attachment') !== -1)
var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
var matches = filenameRegex.exec(disposition);
if (matches != null && matches[1])
filename = matches[1].replace(/['"]/g, '');
filename = filename.replace('UTF-8', '');
var blob = xhr.response;
var url = URL.createObjectURL(blob);
var ttt = document.createElement('a');
ttt.href = url;
ttt.download = filename;
ttt.click();
else
resolve(xhr.response);
)
;
function createParams(parameters)
var params, key;
for (key in parameters)
if (parameters.hasOwnProperty(key))
params = parameters;
return params;
;
function constructRequestDetails(input, url, type, isModuleParam)
var requestDetails = ;
requestDetails.type = type;
if (input != undefined)
if (input.id)
// console.log("IAM HERE 1");
url = url.replace("id", input.id);
// url = url + "/" + input.id;
else
// console.log("IAM HERE 2");
url = url.replace("/id", "");
if (input.params)
// console.log("IAM HERE1 3", input.params, "then", input.module, "hh", isModuleParam);
requestDetails.params = createParams(input.params) + (input.module && isModuleParam ? "module=" + input.module : "");//No I18N
if (!requestDetails.params && isModuleParam)
// console.log("IAM HERE 4");
requestDetails.params = "module=" + input.module;//No I18N
if (input.body && (type == HTTP_METHODS.POST || type == HTTP_METHODS.PUT))
// console.log("IAM HERE 5");
requestDetails.body = JSON.stringify(input.body);
if (input.x_file_content)
// console.log("IAM HERE 6");
requestDetails.x_file_content = input.x_file_content;
if (input.download_file)
requestDetails.download_file = input.download_file;
requestDetails.url = url;
return requestDetails;
;
function getParameterByName(name, url)
if (!url) url = window.location.href;
name = name.replace(/[\[\]]/g, "\\$&");
var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)");
var results = regex.exec(url);
if (!results) return null;
if (!results[2]) return '';
return decodeURIComponent(results[2].replace(/\+/g, " "));
function sdk()
return
initialize: function (configuration)
if (document.getElementById("zes_client_scope") == null)
var elem = document.createElement('div');
elem.setAttribute("data-scope", configuration.scopes);
elem.setAttribute("data-clientid", configuration.clientId);
elem.setAttribute("data-accounts-url", configuration.accountUrl);
elem.setAttribute("id", "zes_client_scope");
document.body.appendChild(elem);
// console.log("initialize", document.body)
var input = ;
ZCRM.API.USERS.get(input).then(function (resp)
);
function actions()
return
convert: function (input)
return promiseResponse(constructRequestDetails(input, "Leads/id/actions/convert", HTTP_METHODS.POST, false));//No I18N
function attachments()
return
uploadFile: function (input)
return promiseResponse(constructRequestDetails(input, input.module + "/id/Attachments", HTTP_METHODS.POST, false));//No I18N
,
deleteFile: function (input)
return promiseResponse(constructRequestDetails(input, input.module + "/id/Attachments/" + input.relatedId, HTTP_METHODS.DELETE, false));//No I18N
,
downloadFile: function (input)
input.download_file = true;
return promiseResponse(constructRequestDetails(input, input.module + "/id/Attachments/" + input.relatedId, HTTP_METHODS.GET, false));//No I18N
,
uploadLink: function (input)
return promiseResponse(constructRequestDetails(input, input.module + "/id/Attachments", HTTP_METHODS.POST, false));//No I18N
,
uploadPhoto: function (input)
return promiseResponse(constructRequestDetails(input, input.module + "/id/photo", HTTP_METHODS.POST, false));//No I18N
,
downloadPhoto: function (input)
input.download_file = true;
return promiseResponse(constructRequestDetails(input, input.module + "/id/photo", HTTP_METHODS.GET, false));//No I18N
,
deletePhoto: function (input)
return promiseResponse(constructRequestDetails(input, input.module + "/id/photo", HTTP_METHODS.DELETE, false));//No I18N
function org()
return
get: function (input)
return promiseResponse(constructRequestDetails(input, "org", HTTP_METHODS.GET, true));//No I18N
function records()
return
get: function (input)
// console.log("zcrm", input);
return promiseResponse(constructRequestDetails(input, input.module + "/id", HTTP_METHODS.GET, false));//No I18N
,
post: function (input)
return promiseResponse(constructRequestDetails(input, input.module + "/id", HTTP_METHODS.POST, false));//No I18N
,
put: function (input)
return promiseResponse(constructRequestDetails(input, input.module + "/id", HTTP_METHODS.PUT, false));//No I18N
,
delete: function (input)
return promiseResponse(constructRequestDetails(input, input.module + "/id", HTTP_METHODS.DELETE, false));//No I18N
,
getNotes: function (input)
return promiseResponse(constructRequestDetails(input, input.module + "/id/Notes", HTTP_METHODS.GET, false));//No I18N
,
getRelated: function (input)
return promiseResponse(constructRequestDetails(input, input.module + "/id/" + input.relatedModule, HTTP_METHODS.GET, false));//No I18N
,
getAllDeletedRecords: function (input)
if (input.params)
input.params.type = "all";
else
input.params =
"type": "all"//No I18N
;
return promiseResponse(constructRequestDetails(input, input.module + "/deleted", HTTP_METHODS.GET, false));//No I18N
,
getRecycleBinRecords: function (input)
if (input.params)
input.type = "recycle";
else
input.params =
"type": "recycle"//No I18N
;
return promiseResponse(constructRequestDetails(input, input.module + "/deleted", HTTP_METHODS.GET, false));//No I18N
,
getPermanentlyDeletedRecords: function (input)
if (input.params)
input.type = "permanent";
else
input.params =
"type": "permanent"//No I18N
;
return promiseResponse(constructRequestDetails(input, input.module + "/deleted", HTTP_METHODS.GET, false));//No I18N
,
search: function (input)
return promiseResponse(constructRequestDetails(input, input.module + "/search", HTTP_METHODS.GET, false));//No I18N
function settings()
return
getFields: function (input)
return promiseResponse(constructRequestDetails(input, "settings/fields/id", HTTP_METHODS.GET, true));//No I18N
,
getLayouts: function (input)
return promiseResponse(constructRequestDetails(input, "settings/layouts/id", HTTP_METHODS.GET, true));//No I18N
,
getCustomViews: function (input)
return promiseResponse(constructRequestDetails(input, "settings/custom_views/id", HTTP_METHODS.GET, true));//No I18N
,
updateCustomViews: function (input)
return promiseResponse(constructRequestDetails(input, "settings/custom_views/id", HTTP_METHODS.PUT, true));//No I18N
,
getModules: function (input)
return promiseResponse(constructRequestDetails(input, "settings/modules" + ((input && input.module) ? "/" + input.module : ""), HTTP_METHODS.GET, false));//No I18N
,
getRoles: function (input)
return promiseResponse(constructRequestDetails(input, "settings/roles/id", HTTP_METHODS.GET, true));//No I18N
,
getProfiles: function (input)
return promiseResponse(constructRequestDetails(input, "settings/profiles/id", HTTP_METHODS.GET, true));//No I18N
,
getRelatedLists: function (input)
return promiseResponse(constructRequestDetails(input, "settings/related_lists/id", HTTP_METHODS.GET, true));//No I18N
function users()
return
get: function (input)
return promiseResponse(constructRequestDetails(input, "users/id", HTTP_METHODS.GET, true));//No I18N
var listener = 0;
function auth()
return
getAccess: function ()
// console.log("inside auth");
if (listener == 0)
// console.log("inside auth 1");
window.addEventListener("storage", function (e)
if (e.key === 'access_token' && e.oldValue != e.newValue && e.oldValue == null)
location.reload();
if (e.key === 'access_token')
localStorage.removeItem('__auth_process');
, false);
listener = 1;
if (localStorage.getItem('__auth_process'))
// console.log("inside auth 2", localStorage.getItem('__auth_process'));
localStorage.removeItem('__auth_process');
var valueInStore = localStorage.getItem('access_token');
// console.log("inside auth 3", valueInStore);
var token_init = localStorage.getItem('__token_init');
// console.log("inside auth 4", token_init);
if (token_init != null && valueInStore != null && Date.now() >= parseInt(token_init) + 55 * 60 * 1000) // check after 55 mins
// console.log("inside auth 5");
valueInStore = null;
localStorage.removeItem('access_token');
var auth_process = localStorage.getItem('__auth_process');
// console.log("inside auth 6", auth_process);
if (valueInStore == null && auth_process == null)
// console.log("inside auth 7");
var accountsUrl = document.getElementById("zes_client_scope").getAttribute("data-accounts-url");
// console.log("inside auth 8", accountsUrl);
var endPoint = "/oauth/v2/auth";
var full_grant = localStorage.getItem('full_grant');
// console.log("inside auth 9", full_grant);
if (full_grant != null && 'true' == full_grant && localStorage.getItem('__token_init') != null)
// console.log("inside auth 10");
endPoint += '/refresh';
var client_id = document.getElementById("zes_client_scope").getAttribute("data-clientid");
var scope = document.getElementById("zes_client_scope").getAttribute("data-scope");
// console.log("inside auth 10", client_id, scope);
var path = window.location.pathname;
// console.log("inside auth 11", path);
// console.log(location.hostname)
var redirect_url = window.location.origin;
// console.log("inside auth 12", redirect_url);
var pathSplit = path.split('/');
var length = pathSplit.length
for (var i = 0; i < length - 2; i++)
redirect_url += pathSplit[i] + "/";
if (location.hostname == "127.0.0.1" || location.hostname == "")
if (length - 2 == 0)
redirect_url += "/";
redirect_url += "app/"
// if ( location.hostname == "localhost" )
//
redirect_url = redirect_url + "/redirect";
// console.log("rediret", redirect_url);
if (client_id && scope)
// console.log("inside auth 13", valueInStore)
localStorage.setItem('__token_init', Date.now());
localStorage.removeItem('access_token');
localStorage.setItem('__auth_process', 'true');
// var popup =
window.open(accountsUrl + endPoint + "?scope=" + scope + "&client_id=" + client_id + "&response_type=token&state=zohocrmclient&redirect_uri=" + redirect_url);//,'', 'width:' + window.innerWidth + ',height:' + window.innerHeight);
// popup.focus();
else
throw 'missing auth params[clientId, redirectUri, scope]';
return valueInStore;
,
revokeAccess: function ()
localStorage.removeItem('crm_access_token');
var ZCRM = (function (argument)
return
API: (function (argument)
return
SDK: new sdk(),
AUTH: new auth(),
RECORDS: new records(),
SETTINGS: new settings(),
ACTIONS: new actions(),
USERS: new users(),
ORG: new org(),
ATTACHMENTS: new attachments()
)(this),
init: function (data)
if (data.constructor === .constructor && data.hasOwnProperty('full_grant') && data['full_grant'] == true)
localStorage.setItem('full_grant', 'true');
)(this)
在您的资产中包含 Zoho CRM SDK 并将其添加到 index.html:
<script src="/assets/js/zcrmsdk.js"></script>
在您的根路径中创建一个 globals.d.ts 并声明 SDK:
declare var ZCRM : any;
现在您可以访问项目中的 SDK。
在您的 app.component.ts 中,您需要在 ngOnInit 处使用正确的配置初始化 SDK:
var configuration = ;
configuration.client_id = CLIENT_ID;
configuration.scopes = SCOPES;
configuration.accounts_url = ACCOUNTS_URL;
ZCRM.API.SDK.initialize(configuration);
继续下一个答案
【讨论】:
以上是关于Angular 应用授权和 Zoho CRM 的问题的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 php 代码将 ZOHO CRM 与 Zapier 连接?