#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()
Пожалуйста, обратите внимание, я не могу поделиться примером кода или ссылками на приложения, поскольку они являются собственностью и не являются общедоступными.