Статьи

Внедрение White-Labeling

Иногда (очень часто по моему опыту) вам нужно поддерживать white-label для вашего приложения. Обычно вы можете запускать его в режиме SaaS, но некоторые важные или высокопрофильные клиенты могут потребовать либо выделенного развертывания, либо локального развертывания, либо просто «своего угла» в вашем облачном развертывании.

Белая маркировка обычно включает в себя разные CSS, разные логотипы и другие изображения, а также разные тексты верхнего и нижнего колонтитула. Остальная часть продукта остается прежней. Так как же мы поддерживаем маркировку белым цветом как можно менее инвазивным способом? (Я буду использовать Spring MVC в моих примерах, но довольно просто перенести логику на другие фреймворки)

Во-первых, давайте наметим три различных способа поддержки белой маркировки. Вы можете (и, вероятно, должны) реализовать их все, так как они полезны в разных сценариях и имеют много общего.

  • Установка с белой маркировкой — измените стили всего развертывания. Полезно для локальных или управляемых установок.
  • Субдомен с белой меткой — разрешить доступ к различным стилям сервиса через определенный субдомен
  • Белые метки клиента (-ов) — позволяют определенным клиентам после входа в систему видеть настроенные стили

Чтобы реализовать полную установку с белой маркировкой , нам нужно настроить путь в файловой системе, куда будут помещены настроенные файлы CSS и изображения, а также настроенные тексты. Вот пример из файла .properties, переданного приложению при запуске:

1
2
3
4
5
styling.dir=/var/config/whitelabel
styling.footer=©2018 Your Company
styling.logo=/images/logsentinel-logo.png
styling.css=/css/custom.css
styling.title=Your Company

При весенней / весенней загрузке вы можете сервировать файлы из файловой системы, если сопоставлен определенный шаблон URL. Например:

01
02
03
04
05
06
07
08
09
10
11
@Component
@Configuration
public class WebMvcCustomization implements WebMvcConfigurer {
  @Value("${styling.dir}")
  private String whiteLabelDir;
 
  @Override
  public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/whitelabel/**").addResourceLocations(whiteLabelDir);
  }
}

И, наконец, вам нужно настроить шаблоны HTML, но мы вернемся к этому в конце, когда все остальные параметры будут реализованы.

Далее идут белые субдомены . Для меня это лучший вариант, так как он позволяет вам иметь одну установку с несколькими клиентами с определенными стилями. Стиль зависит исключительно от домена / субдомена, через который осуществляется доступ к услуге.

Для этого нам нужно ввести сущность WhitelabelStyling и соответствующую таблицу базы данных. Мы можем сделать некоторый пользовательский интерфейс администратора, чтобы настроить это, или настроить его непосредственно в базе данных. Сущность может выглядеть примерно так:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
@Table("whitelabel_styling")
public class WhitelabelStyling {
    @PrimaryKey
    private String key;
    @Column
    private String title;
    @Column
    private String css;
    @Column
    @CassandraType(type = DataType.Name.BLOB)
    private byte[] logo;
    @Column
    private String footer;
    @Column
    private String domain;
 
   // getters and setters
}

Ключ — произвольная строка, которую вы выбираете. Это может быть то же самое, что и (суб) домен или какая-либо другая бизнес-значимая строка. Остальное в основном очевидно. После того, как у нас есть это, мы должны быть в состоянии обслуживать ресурсы. Для этого нам нужен контроллер, который вы можете увидеть здесь . Контроллер берет ключ с белой меткой и пытается загрузить соответствующую запись из базы данных, а затем передает результат. /whitelabel-resources/logo.png точки контроллера в этом случае — /whitelabel-resources/logo.png и /whitelabel-resources/style.css .

Чтобы установить правильный ключ для конкретного субдомена, вам необходим атрибут модели для каждого запроса (т. Е. Значение, которое устанавливается в модели всех отображаемых страниц). Примерно так (который обновляет кэш белой метки один раз в день; кеш обязателен, если вы не хотите обращаться к базе данных при каждом запросе):

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
@ModelAttribute("domainWhitelabel")
public WhitelabelStyling perDomainStyling(HttpServletRequest request) {
    String serverName = request.getServerName();
    if (perDomainStylings.containsKey(serverName)) {
        return perDomainStylings.get(serverName);
    }
    return null;
}
 
@Scheduled(fixedRate = DateTimeConstants.MILLIS_PER_DAY)
public void refreshAllowedWhitelabelDomains() {
     perDomainStylings = whitelabelService.getWhitelabelStyles()
            .stream()
            .collect(Collectors.toMap(WhitelabelStyling::getDomain, Function.identity()));
}

И, наконец, маркировка для каждого клиента достигается так же, как и выше, при использовании того же контроллера, только текущий ключ выбирается не на основе request.getServerName() а на основе свойства аутентифицированного пользователя. Администратор (через пользовательский интерфейс или непосредственно в базе данных) может назначить ключ whitelabel каждому пользователю, а затем, после входа в систему, этот пользователь видит настроенный стиль.

Мы видели, как выглядит Java-часть решения, но нам нужно изменить шаблоны HTML, чтобы выбрать настройки. Простой подход будет выглядеть следующим образом (с использованием шаблонов pebble):

1
2
3
4
5
6
7
8
9
{% if domainWhitelabel != null %}
  <link href="/whitelabel-resources/style.css?key={{ domainWhitelabel.key }}" rel="stylesheet">
{% elseif user.whitelabelStyling != null and user.whitelabelStyling.css != '' %}
  <link href="/whitelabel-resources/style.css" rel="stylesheet">
{% elseif beans.environment.getProperty('styling.dir') != '' and beans.environment.getProperty('styling.css.enabled') == true %}
  <link href="{{'/whitelabel/'+  beans.environment.getProperty('styling.css')}}" rel="stylesheet">
{% else %}
  <link href="{{ beans.environment.getProperty('styling.css')}}" rel="stylesheet">
{% endif %}

Это довольно просто — если настроена белая маркировка на уровне домена, используйте ее; в противном случае проверьте, назначен ли текущий пользователь определенной белой метке; если нет, проверьте, настроена ли глобальная установка белой маркировки; если нет, используйте значение по умолчанию. Этот фрагмент использует вышеупомянутый WhitelabelController (в первых двух случаях) и пользовательский обработчик ресурсов в предпоследнем случае.

В целом, это гибкое и простое решение, которое может занять не более нескольких дней для внедрения и тестирования даже на существующих системах. Я еще раз озвучу свое предпочтение стилям на основе домена, поскольку они позволяют использовать одну и ту же мультитенантную установку со многими различными стилями и логотипами. Конечно, ваш веб-сервер / балансировщик нагрузки / домен должен быть правильно настроен, чтобы разрешить использование поддоменов и позволять вам легко ими управлять, но это оффтоп.

Я думаю, что белая маркировка — это хороший подход для многих продуктов. Очевидно, что не реализуйте это, пока это не понадобится бизнесу, но имейте в виду, что это может прийти в упадок, и это относительно легко реализовать.

Опубликовано на Java Code Geeks с разрешения Божидара Божанова, партнера нашей программы JCG . Смотрите оригинальную статью здесь: Внедрение White-Labeling

Мнения, высказанные участниками Java Code Geeks, являются их собственными.