Sendgrid品牌链接与Nginx代理

时间:2018-08-28 07:43:34

标签: nginx proxy sendgrid

我们尝试通过此文档https://sendgrid.com/docs/ui/account-and-settings/custom-ssl-configurations/设置带有自定义ssl的品牌链接。

我们遵循它,现在我们有了一个带有证书的代理,并将其重定向到sendgrid.net。

支持人员告诉我们,他们的测试内容为“失败:我们没有从测试'https'点击跟踪链接中获得200响应。”并告诉我们不支持代理上的证书通配符。

我不理解通配符的原因,代理不发送200,因为sendgrid.net发送404

所以我不知道该怎么办。

我们使用nginx和本示例来实现我们的代理:https://gist.github.com/jjhiew/cbbd26da313fc550467e303a6c6f8177

1 个答案:

答案 0 :(得分:0)

感谢您的提醒。我们确实有工作,但是我忘了在这里发布。总体思路是 品牌点击请求已转到我们自己的服务器,该服务器具有TLS认证。即link.mysite.com 去我们自己的服务器而不是SendGrid。我们的服务器接受这些请求,使相同 请求发送到SendGrid。无论SendGrid回复我们的服务器如何,我们都会发回浏览器。

我不确定,但是我认为SendGrid支持人员必须进行一些切换。但这可能是错误的。我确实记得我曾与他们交谈过,并且我记得他们不了解这种代理情况。我不确定是否最终找到了一个做到这一点的人,或者在没有他们的情况下让它工作了,我不确定。

以下是我们为此使用的代码(Ruby on Rails):

# Allow SendGrid Click Tracking to use HTTPS
#
# SendGrid click tracking uses the host 'link.example.com' but HSTS requires that host
# respond to HTTPS. However SendGrid does not have our certificate. So instead point
# link.example.com to this proxy, and we make the same request to sendgrid.
#
# see: https://sendgrid.com/docs/ui/account-and-settings/custom-ssl-configurations/
#
# Configuring SendGrid, Heroku, and DNSimple for Click Tracking and unsubscribes
# ------------------------------------------------------------------------------
#   Sendgrid > Sender Authentication > Link Branding
#     Create branded link for example.com
#     Advanced Settings > Custom link subdomain: link
#
#   DNS > make the CNAME records they mention
#   Sendgrid >
#     verify branded links so they are activated.
#     Make link the default.
#
#   Heroku > configure subdomain for link.example.com
#   DNS > change CNAME record so link.example.com points to Heroku, e.g. blah.blah.herokudns.com
#
#   Test:
#       Unsubscribe links that start with link.example.com/___ should work now.
#
#   Sendgrid > Tracking > Click Tracking > ON
#
#   Test:
#     Send a test Frisky Friday.
#     Follow link to article--it should start with link.example.com
#     SendGrid increments the Click Tracking counter
class SendgridLinkProxyController < ActionController::Base
  SENDGRID_CLICK_TRACKING_URL = 'https://sendgrid.net'.freeze

  def index
    # Make matching request to SendGrid
    sendgrid_url = URI.parse("#{SENDGRID_CLICK_TRACKING_URL}#{request.env['ORIGINAL_FULLPATH']}").to_s
    sendgrid_headers = { 'Host' => CFG.SENDGRID_PROXY_HOSTNAME }

    Rails.logger.info("sendgrid_link_proxy_controller.rb: fetching #{sendgrid_url}, headers: #{sendgrid_headers}")
    sendgrid_response = HTTParty.get(sendgrid_url, headers: sendgrid_headers, follow_redirects: false) # , debug_output: STDOUT)

    # Make matching response to browser
    user_response_status = sendgrid_response.code
    response.set_header('location', sendgrid_response.headers['location'])
    Rails.logger.info("sendgrid_link_proxy_controller.rb: responding status_code: #{user_response_status}, location header: #{response.header['location']}")
    render html: sendgrid_response.body.html_safe, # We are trusting SendGrid. Winston think's that's OK. [Winston Dec 2018]
           status: user_response_status
  end
end

下面是一个RSpec文件:

require 'spec_helper'

describe SendgridLinkProxyController do

  describe '#index' do
    before do
      @sendgrid_response = {
        headers: {},
        body: '<html>SENDGRID BODY</html>',
        code: 200
      }
      request.env['ORIGINAL_FULLPATH'] = '/wf/click?upn=BLAH'
      CFG.SENDGRID_PROXY_HOSTNAME = 'link.example.com'
    end

    subject do
      allow(HTTParty)
        .to receive(:get)
        .and_return(double('Mock Sendgrid Response', @sendgrid_response))
      get :index, params: {a: 'click'}
    end

    it 'requests page from sendgrid with same path and with Host header' do
      expect(HTTParty).to receive(:get)
        .with('https://sendgrid.net/wf/click?upn=BLAH',
              headers: { 'Host' => 'link.example.com' },
              follow_redirects: false
             )

      subject
    end

    context 'when receiving a click-tracking redirect link' do
      before do
        @sendgrid_response[:code] = 302
        @sendgrid_response[:headers]['location'] = 'https://example.com/TARGET'
      end

      it 'redirects browser to target link' do
        subject

        expect(response.status).to eq(302)
        expect(response.headers['location']).to eq('https://example.com/TARGET')
      end
    end

    context 'when receiving an unsubcribe link' do
      before do
        request.env['ORIGINAL_FULLPATH'] = '/wf/unsubscribe?upn=BLAH'
      end

      it 'renders sendgrid\'s unsubscribe page' do
        subject

        expect(response.body).to eq('<html>SENDGRID BODY</html>')
      end
    end
  end
end