Как хранить данные аутентификации для RESTful API

#angular #rest #authentication #restful-authentication

#angular #rest #аутентификация #restful-аутентификация

Вопрос:

Я разрабатываю приложение Angular, которое использует RESTful API. Аутентификация выполняется с помощью базового заголовка авторизации HTTP.

Как лучше всего хранить учетные данные для отправки с каждым запросом? Поскольку он не имеет состояния RESTful, нет ни cookie, ни токена. Кроме локального хранилища, я не вижу решения, и мне это не нравится, поскольку оно может быть украдено с помощью JS-инъекции.

Ответ №1:

Вы можете сохранить их в зашифрованном виде в localstorage:

  1. Зашифруйте свой ответ
  2. Сохраните его в localStorage
  3. Расшифруйте значение из localStorage, если вы хотите его использовать

Комментарии:

1. Ключ шифрования должен храниться в браузере, поэтому любому злоумышленнику будет разрешено расшифровать учетные данные, не так ли?

2. Как насчет их шифрования в API?. Я просто пытаюсь придумать хорошее решение.

Ответ №2:

Есть файл cookie! Это делается с помощью безопасных файлов cookie.

 signUp(email: string, password: string, passwordConfirm: string, name: string): Observable<User> {
    const url = `${this.BASE_URL}/users/signup`;
    return this.http.post<User>(url, {email, password, passwordConfirm, name}, {
      withCredentials: true, // this part is very important
    });
  }
  
 //Node js 
const createAndSendToken = (user, statusCode, req,res) => {
  const token = signToken(user._id, user.name);
  const cookieOptions =  { 
    expires: new Date(
      Date.now()   process.env.JWT_COOKIE_EXPIRES_IN * 24 * 60 * 60 * 1000
      ),
      httpOnly: true
  }

  // if(process.env.NODE_ENV === 'production') cookieOptions.secure = true;

  if(req.secure || req.headers('x-forwarded-proto') === 'https') cookieOptions.secure = true; //this part is for heroku, it's important to have secure option set to true inside cookieOptions

  res.cookie('jwt', token, cookieOptions);
  
  user.password = undefined;

  res.status(statusCode).json({
    status: 'success',
    token,
    data: {
      user
    }
  })
}
  

После этого внутри вы устанавливаете параметры cors только для одного источника, и учетные данные должны быть истинными.
Соединение должно проходить по протоколу https. Если все работает нормально, cookie-файл будет сохранен автоматически. Откройте консоль, затем приложение в хранилище, в котором у вас есть файлы cookie, и проверьте, есть ли файл cookie. При каждом запросе у вас будет доступ к cookie внутри Rest Api

 exports.isLoggedIn = async (req, res, next) => {
  if (req.cookies.jwt) {
    try {
  // 1) Verification token
  const decoded = await promisify(jwt.verify)(req.cookies.jwt, process.env.JWT_SECRET)
  
  // 2) Check if user still exists
  const currentUser = await User.findById(decoded.id);
  
  if(!currentUser) {
    return next();
  }

  // 4) Check if user changed password after the token was issued
  if(currentUser.changedPasswordAfter(decoded.iat)) {
    return next()
  }
  //THERE IS A LOGGED IN USER
  req.user = currentUser;
  return next();  

  } catch(err) {

    return next();
  }   
    
  }
  next();
}
  

При каждой перезагрузке внутри приложения angular мы вызываем эту функцию.