SalesForce canvas app oauth Web服务器流程,用户交互最少

时间:2015-08-14 04:08:13

标签: oauth salesforce

因此,我正在权衡SalesForce Canvas应用程序的不同身份验证机制的优缺点。

首先,一点背景。我有一个现有的网络应用程序 - 让我们称之为" myapp"。我设置了一个包含VisualForce页面的VisualForce选项卡,该页面通过以下方法嵌入我的画布应用程序:

<apex:page>
    <apex:canvasApp applicationName="___________" />
</apex:page>

我首先通过签名的请求方法实现了访问权限,这非常棒,因为用户只需在第一次访问时接受我的应用程序权限,随后尝试访问我的画布应用程序就可以直接进入myapp主页

从阅读this article关于打包不同SalesForce版本的画布应用程序,签名请求方法有一个限制:

  

大多数典型的Group and Professional Edition客户无法使用您的签名请求连接应用程序,除非他们升级到EE或更高版本或作为插件购买这些功能。

所以我决定切换到oauth工作流程。

查看user agent oauth flow documentation,它说:

  

用户必须始终批准此身份验证流程的访问权限。批准访问后,应用程序将从Salesforce接收回调。

这也是不可取的,但是the web server oauth flow没有这个要求 - 一旦用户接受了应用程序的权限要求,就不需要提示他们再次执行此操作。它还可以添加一个&#34; Login with SalesForce&#34; myapp登录页面上的选项非常容易添加。

因此,我设置了Web服务器oauth流程,并使一切运行良好,并且作为一个额外的好处添加了一个&#34;使用SalesForce登录&#34;登录页面的选项 - 很棒。

下一步是在VisualForce选项卡中设置画布应用程序以启动Web服务器oauth流程。

我想解决的问题:

我想使用Web服务器oauth流程从VisualForce选项卡访问myapp的主页,在此过程中尽可能少的用户交互。

基本设置

为了启动oauth流程,我已经设置了一个URL,其中包含以下逻辑,以便制作从其他地方启动流程的链接。这可以从以下每个示例中使用,并由/salesforce/oauth/.....的链接引用。

// Allow links to this page to specify "state" and "prompt" paramaters.
$state  = isset($_GET['state'])  ? $_GET['state']  : 'login';
$prompt = isset($_GET['prompt']) ? $_GET['prompt'] : '';

// Canvas app contextual information provides the right SalesForce endpoint domain, so provide a way for that to be passed in here, or fallback to standard login.salesforce.com for other workflows.
$authDomain = isset($_GET['authDomain']) ? $_GET['authDomain'] : 'https://login.salesforce.com/services/oauth2/authorize';

$url = $authDomain.'?'.http_build_query(array(
    'response_type' => 'code',
    'client_id'     => 'XXXXXXX_MY_APP_CLIENT_ID',
    'redirect_uri'  => 'https://'.$_SERVER['HTTP_HOST'].'/salesforce/authorize/',
    'state'         => $state,
    'prompt'        => $prompt,
));

header('Location: '.$url);
die;

尝试失败1

使用javascript canvas sdk,重定向画布应用程序以启动我的Web服务器oauth流程:

location.href = '/salesforce/oauth?authUrl='+encodeURIComponent(Sfdc.canvas.oauth.loginUrl())+'&state=canvas';

我遇到了这种方法的两个问题:

  1. 画布应用程序会丢失其中#query片段提供的上下文信息。
  2. 具有接受/拒绝权限的SalesForce页面的
  3. X-Frame-Options标题会阻止它在iframe中显示,甚至在SalesForce域上。
  4. 我觉得如果能够克服这些问题,这将是实现目标的最佳方式。

    我实际上做了一个实验,通过在我的画布应用程序中的另一个iframe中加载该URL来解决问题#1,如果我已经接受了完美无缺的myapps权限要求,那么我仍然遇到问题# 2当弹出权限屏幕并且整个过程未能完成时。

    当前解决方案

    我已经使初始画布应用页面包含一个要点击的按钮,这将在新窗口中打开Web服务器oauth流,并在该窗口中成功完成。完成后,画布应用iframe将重定向到我的应用主页。

    我对此不满意,因为每次点击我的VisualForce标签时,都需要用户点击按钮,然后弹出一个新窗口来运行oauth工作流程。如果用户之前已经接受了应用程序权限,它会自动关闭,无需额外的用户交互,如果用户尚未接受应用程序权限,则会提示他们接受,然后自行关闭。

    如果我坚持使用这个解决方案,那不是世界末日 - 我们会把那个按钮变成一个闪屏,里面有一些营销废话和一个令人讨厌的&#34 ;继续阅读MyApp&#34;按钮在某处。

    问题(......最后)

    有没有什么方法可以删除每次加载画布应用程序时单击按钮的必要步骤,但是继续使用Web服务器oauth流程? (记住我不想使用用户代理oauth流,因为每次用户访问时都有类似的接受权限的要求)。

    当画布应用程序嵌入到SalesForce帐户或联系人屏幕中时,额外的步骤尤其令人讨厌 - 因为它阻止我的应用程序加载并向用户显示数据,直到用户点击按钮。

1 个答案:

答案 0 :(得分:0)

要么我没有得到它,要么那很简单。您需要使用oAuth immediate参数:

  

immediate - 确定是否应提示用户进行登录和批准。此参数是可选的。如果指定,则值必须为true或false。默认值为false。请注意以下事项:   如果设置为true,并且用户当前已登录并且之前已批准client_id,则Salesforce会跳过批准步骤。   如果设置为true且用户未登录或之前未批准客户端,则Salesforce会立即终止并显示immediate_unsuccessful错误代码。

来源:12

唯一的问题是最后一部分:如果用户尚未授权您的应用,您将收到错误消息。根据我使用oAuth的经验,使用Javascript从客户端浏览器本身运行请求会更加容易。您可以发出immediate = true请求,并在immediate = false之后发出请求,以防第一个失败。然后通过创建第三个请求将access_token发送到您的应用程序 - 发送到您自己的服务器。