Angular / MongoDB / NodeJS: автоматический вход из одного домена в другой домен

#node.js #angular #mongodb #jwt

#node.js #angular #mongodb #jwt

Вопрос:

В моем приложении я управляю двумя доменами; один находится http://localhost:4500 , а другой включен http://localhost:4600

Теперь сценарий заключается в том, что при входе в http://localhost:4500 домен с использованием этих учетных данных я также хочу создать реализацию, которая будет автоматически входить в http://localhost:4600 домен при нажатии на got-to-front-panel ссылку для этого конкретного пользователя, который вошел в систему http://localhost:4500 домен.

Для http://localhost:4500 домена у меня есть приложение Angular, для которого я управлял externalUrl процессом маршрутизации.

app-routing.module.ts

 {
    path: "go-to-front-panel",
    canActivate: [RedirectGuard],
    component: RedirectGuard,
    data: {
      externalUrl: "http://localhost:4600"
    }
}
 

перенаправление-guard.service.ts

 export class RedirectGuard implements CanActivate {

  constructor(private router: Router) { }

  canActivate({ data }: ActivatedRouteSnapshot): boolean {
    window.open(data.externalUrl, '_blank');
    return false;
  }
}
 

При входе в http://localhost:4500 домен он сохраняет приведенные ниже значения json в таблице mongodb

 {
    "_id" : ObjectId("5fcb088781f14e2f783eq262"),
    "userId" : 1,
    "token" : "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImp0aSI6IjM4Njk4NWUyLTc5MTItNDZhMy04YjY5LWMxYTdhZDQ2OWRhMSIsImlhdCI6MTYwNzQxMDMxMSwiZXhwIjoxNjA3NDEzOTExfQ.0czxMiH7yblJWxIepzHbq7C8oVde01kFnKnScC54LW4",
    "createdAt" : "2020-11-08 15:00:55",
    "deactivatedAt" : null,
    "__v" : 0
}
 

и в хранилище сеансов он сохраняет значение токена этого домена http://localhost:4500

login.component.ts

sessionStorage.setItem('token', userDetails.token);

=> Значение токена генерируется с использованием jwt.sign метода, как показано ниже.

 const token = jwt.sign({ userDetails }, SECRET_KEY);
 

=> Итак, как я могу управлять автоматическим входом из http://localhost:4500 домена в http://localhost:4600 домен

введите описание изображения здесь

Ответ №1:

Я бы не сказал, что это автоматический вход в систему.

Но когда вы нажмете на got-to-front-panel , вы можете попытаться выполнить следующую процедуру.

(1) Извлечение серверной части для одноразового использования. Одноразовый номер сможет идентифицировать пользователя. Вы можете сохранить одноразовый номер в redis или что-то, срок действия которого истекает через 5-10 секунд.

(2) добавьте одноразовый номер к http://localhost:4600?/nonce=some-very-long-unique-string-like-uuid

(3) http://localhost:4600 свяжитесь с серверной частью с одноразовым номером для проверки подлинности. Серверная часть истекает одноразовый номер и отвечает токеном аутентификации.

(4) http://localhost:4600 получает токен аутентификации и сохраняет его в localstorage

Это поведение аналогично тому, как вы выполняете аутентификацию в Google / facebook и перенаправляете на желаемый URL-адрес с уникальным кодом для аутентификации.

Другой метод чем-то похож.

(1) Логин пользователя http://localhost:4700 , получить токен аутентификации

(2) Пользователь перенаправлен на http://localhost:4800/redirect-url/?token=sometoken

(3) полная аутентификация на http://localhost:4800 путем сохранения токена в localstorage или с помощью вашего собственного механизма аутентификации

(4) перенаправить обратно на http://localhost:4700

(5) viola, сохраненный логин для обоих доменов.

Ответ №2:

Поскольку разные порты локального хоста рассматриваются как разные домены, никто не может получить доступ к другим ресурсам, таким как файлы cookie или localStorage.

Если эти два приложения будут развернуты в подкаталогах одного и того же домена во время производства (company.com/app1 и company.com/app2 ), можно получить доступ к чужому ресурсу, и автоматический вход в систему будет работать без каких-либо проблем.

(Это моя точная ситуация, и у меня есть 4 разных приложения angular, которые используют одни и те же данные для входа. Поскольку они находятся в одном домене и между ними установлено деловое доверие, когда пользователь входит в одно приложение, другие приложения при открытии автоматически регистрируют его, используя те же данные localStorage, и по истечении срока действия любой из них обновит токен, а другие будут использовать тот же новый токен)

В противном случае вы можете добиться этого с помощью postMessage api.

т.е. У вас может быть (скрытый) iframe в приложении 4600, и когда оно открыто, оно может загрузить 4500 в iframe и с соответствующим обработчиком, написанным в 4500, 4600 может сделать запрос с использованием postMessage api, а 4500 может отправить данные для входа, присутствующие в нем. Это может быть реализовано без использования фреймов путем обмена данными между всплывающим окном и его родителем, например

 window.parent.postMessage()
 

Пожалуйста, обратите внимание, я не могу поделиться примером кода или ссылками на приложения, поскольку они являются собственностью и не являются общедоступными.