Angular 8 Login не устанавливает файлы cookie должным образом - PullRequest
0 голосов
/ 11 декабря 2019

Это система входа в систему, написанная на Angular 8 FrontEnd и Express.js (Node.js) BackEnd.

Моя цель состоит в том, чтобы войти в систему пользователя, поместив в /api/login данные для входа в систему, где используется вход в систему. проверил и получил ответ с набором файлов cookie (в формате имени ключа access_token и содержимого Bearer <jwt token here>) для дальнейшей авторизации, а также для перенаправления на панель инструментов. /api/login отвечает кодом состояния 200 в случае успешного входа в систему с указанным заголовком набора файлов cookie (он же новый файл cookie) с httpOnly:true с ответом.

Моя проблема в том, что сследующий код я получаю эту ошибку, и я не получаю перенаправления и нет cookie:

Http failure during parsing for http://localhost:3000/api/login"

Мой код следующий:

login(username: string, password: string) {
        return this.http.post<any>(`${environment.apiUrl}/api/login`, { username, password })
            .pipe(map(user => {
                // login successful if there's a jwt token in the response
                if (user && user.token) {

                    // store user details and jwt token in local storage to keep user logged in between page refreshes
                    // https://dev.to/rdegges/please-stop-using-local-storage-1i04
                    localStorage.setItem('currentUserToken', JSON.stringify(user));
                    this.currentUserSubject.next(user);
                }
                console.log('User:', user);
                return user;
            }));
    }

PS LocalStorage устарела, и куки используются для аутентификации иавторизация.


Если я добавлю responseType: 'text', я получу следующие ошибки:

No overload matches this call.
  Overload 1 of 15, '(url: string, body: any, options: { headers?: HttpHeaders | { [header: string]: string | string[]; }; observe: "events"; params?: HttpParams | { [param: string]: string | string[]; }; reportProgress?: boolean; responseType?: "json"; withCredentials?: boolean; }): Observable<...>', gave the following error.
    Type '"text"' is not assignable to type '"json"'.
  Overload 2 of 15, '(url: string, body: any, options: { headers?: HttpHeaders | { [header: string]: string | string[]; }; observe: "response"; params?: HttpParams | { [param: string]: string | string[]; }; reportProgress?: boolean; responseType?: "json"; withCredentials?: boolean; }): Observable<...>', gave the following error.
    Type '"text"' is not assignable to type '"json"'.
  Overload 3 of 15, '(url: string, body: any, options?: { headers?: HttpHeaders | { [header: string]: string | string[]; }; observe?: "body"; params?: HttpParams | { [param: string]: string | string[]; }; reportProgress?: boolean; responseType?: "json"; withCredentials?: boolean; }): Observable<...>', gave the following error.
    Type '"text"' is not assignable to type '"json"'.

Мой код бэкэнда:

app.post('/api/login', apiLimiter, async function (req, res){
  // TODO: implement cookie check whether a still valid token is set and if so respond with cookie already set
  try  {
    let [sorted,users] = await getSorted();
    const pw = req.body.password;
    const hashedPassword = await bcrypt.hash(req.body.password, 10);
    console.log(await bcrypt.compare('testtest',hashedPassword));
    // const user = { id: req.body.id, username: req.body.username, password: req.body.password };
    var user = new User({firstname: req.body.firstname, eMail: req.body.eMail, password: hashedPassword });
    sorted.forEach(async ([firstname, password]) => {
      let result = bcrypt.compareSync(pw, password);
        // r = true if hash = hashed pw
        if (result === true) {
          jwt2.sign({user}, 'secrethere', { expiresIn: '15min'}, (err, token) =>{
            res.cookie(
              'access_token', 'Bearer '+ token, {
                expires: new Date(Date.now() + 900000), // cookie will be removed after 15 mins
                httpOnly: true
              })
            .send(200)
              .redirect(
                'http://localhost:4200/avior/dashboard'
              );
          });
          zehgreatresult = 1;
        } else{
          zehgreatresult = 0;
        }

    });    
  } catch (err) {
    res.status(500).send()
    console.log(err);
  }
  if (zehgreatresult === 0){
    res.send("Wrong password!");
  }
});

Мой новый код, содержащий redir, который по какой-то причине не работает:

login(username: string, password: string) {
        return this.http.post<any>(`${environment.apiUrl}/api/login`, { username, password }, {withCredentials: true})
            .pipe(map(user => {
                // login successful if there's a jwt token in the response
                if (user && user.token) {

                    // store user details and jwt token in local storage to keep user logged in between page refreshes
                    // https://dev.to/rdegges/please-stop-using-local-storage-1i04
                    localStorage.setItem('currentUserToken', JSON.stringify(user));
                    this.currentUserSubject.next(user);
                }
                console.log('User:', user);
                this.redirtoDashboard();
                return user;

            }));
    }
 redirtoDashboard() {
      this.router.navigate(['http://localhost:4200/avior/dashboard']);
    }

Ответы [ 2 ]

0 голосов
/ 11 декабря 2019

По умолчанию служба Http ожидает данных JSON, но ваш API отправляет другую форму, возможно простой текст, поэтому у вас есть 2 решения: - Попробуйте изменить код API для отправки закодированных данных JSON в PHP, например, мыиспользуйте: json_encode funtion, в .Net JsonConvert.SerializeObject function ... - Если у вас нет доступа к вашему APi, попробуйте заставить HTTP-сервис получать текстовые данные, добавив следующую опцию:

this.http.post(
    `${environment.apiUrl}/api/login`,
    { username, password },
    {responseType: 'text'})
0 голосов
/ 11 декабря 2019

это должен быть немного другой способ выполнения запросов. вы должны использовать withCredentials: true в качестве параметров для http-методов, подобных этому

http.get(someUrl, {withCredentials: true});
http.post(someUrl, body, {withCredentials: true});

с этой опцией: 1: УСТАНОВИТ ваши куки и 2: прикрепит ваши существующие куки к запросу

...