• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Token ma wartość null przy korzystaniu z JWT, Angular

VPS Starter Arubacloud
+1 głos
391 wizyt
pytanie zadane 13 stycznia 2021 w JavaScript przez HowToIT Początkujący (290 p.)

Piszę stronę logowania z wykorzystaniem JWT, jednak w zbadaj element/ Application ciągle otrzymuję token równy null lub undefined, ale w konsoli wypisuje mi string. Z czego może to wynikać? 

UserService.ts

import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
import { Observable } from 'rxjs';
import { serializeNodes } from '@angular/compiler/src/i18n/digest';
import { tap } from 'rxjs/operators';
@Injectable({
  providedIn: 'root'
})
export class UserService {

  baseurl = "http://127.0.0.1:8000";
  httpHeaders = new HttpHeaders({'Content-Type':'application/json'});
  constructor(private http: HttpClient) { }

  login(username, password): Observable<any>{
    //console.log(this.http.post(this.baseurl + '/api/v1/rest-auth/login/', {username, password}));
    //return this.http.post(this.baseurl + '/api/v1/rest-auth/login/', {username, password});
   return this.http.post<{token:  string}>(this.baseurl + '/api/v1/rest-auth/login/', {username, password}).pipe(
     tap(
       res => {
    localStorage.setItem('token', JSON.stringify(res.token));
    }))

  }
  register(email:string, password:string) {
    return this.http.post<{token: string}>(this.baseurl + '/api/v1/rest-auth/register/', {email, password}).pipe(tap(res => {
    this.login(email, password)
  }))
  }

  logout() {
    localStorage.removeItem('token');
  }

  public get loggedIn(): boolean{
    return localStorage.getItem('token') !==  null;
  }

  getToken(){
    return localStorage.getItem('token');
  }

Wiem, że powinnam użyć JSON.parse w getToken,ale wtedy otrzymuję ten error:


 
SyntaxError: Unexpected token u in JSON at position 0
    at JSON.parse (<anonymous>)
    at UserService.getToken (user.service.ts:40)
    at JwtService.intercept (jwt.service.ts:16)
    at HttpInterceptorHandler.handle (http.js:1258)
    at HttpXsrfInterceptor.intercept (http.js:1895)
    at HttpInterceptorHandler.handle (http.js:1258)
    at HttpInterceptingHandler.handle (http.js:1945)
    at MergeMapSubscriber.project (http.js:1082)
    at MergeMapSubscriber._tryNext (mergeMap.js:44)
    at MergeMapSubscriber._next (mergeMap.js:34)

JwtService.ts

import { Injectable, Injector } from '@angular/core';
import { HttpInterceptor } from '@angular/common/http';
import { UserService } from './user.service';

@Injectable({
  providedIn: 'root'
})
export class JwtService implements HttpInterceptor{

  constructor(private injector: Injector) { }

  intercept(req, next){
    let serv = this.injector.get(UserService)
    let tokenizedReq = req.clone({
      setHeaders: {
        Authorization: `Bearer ${serv.getToken()}` 
      }
    })
    return next.handle(tokenizedReq)
  }
}

login.component.ts

import { Component, OnInit,EventEmitter, Output } from '@angular/core';
import { User } from 'src/app/models/user';
import { Router, ActivatedRoute } from '@angular/router';
import { UserService } from './../../services/user.service';
@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css'],
  providers: [UserService]
})
export class LoginComponent implements OnInit {

  username = '';
  password = '';
  constructor(private api:UserService, private router: Router) { }
  StudentLogin = false;
  DeanLogin = false;
  AdminLogin = false;
  token = "";
  ngOnInit(): void {
  }

  showStudentLogin(){
    this.StudentLogin = true;
    this.DeanLogin = false;
    this.AdminLogin = false;
  }

  login(){
    this.api.login(this.username, this.password).subscribe(
      response => {
        this.token = response;
        console.log(response);
        alert(response)
        this.router.navigate(['/student'])
        console.log(this.api.loggedIn)
      },
      error =>{
        console.log("nie ok");
        console.log(error)
      }
    );
  }

}

app.modules.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HeaderComponent } from './components/layout/header/header.component';
import { NavigationComponent } from './components/layout/navigation/navigation.component';
import { LoginComponent } from './components/login/login.component';
import { StudentComponent } from './components/student/student.component';
import { DeanComponent } from './components/dean/dean.component';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { AdminComponent } from './components/admin/admin.component';
import { FormsModule } from '@angular/forms';
import { JwtModule } from '@auth0/angular-jwt';
import { JwtService } from './services/jwt.service';

@NgModule({
  declarations: [
    AppComponent,
    HeaderComponent,
    NavigationComponent,
    LoginComponent,
    StudentComponent,
    DeanComponent,
    AdminComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule,
    AppRoutingModule,
    FormsModule
  ],
  providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: JwtService,
      multi: true
    }
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

Jestem całkowicie nowa w Angularze, więc jest to zlepek tutoriali i nie jestem pewna gdzie szukać błędu. Dziękuję za wszystkie wskazówki.

komentarz 13 stycznia 2021 przez ScriptyChris Mędrzec (190,190 p.)

jednak w zbadaj element/ Application ciągle otrzymuję token równy null lub undefined 

Masz na myśli panel Local Storage w zakładce Application?

w konsoli wypisuje mi string.

W którym miejscu powyższego kodu jest to wypisywane do konsoli?

Wiem, że powinnam użyć JSON.parse w getToken,ale wtedy otrzymuję ten error:

Pokaż jakimś console.log'iem co w ogóle zwraca ta funkcja, bo nie bez przyczyny JSON.parse nie może tego sparsować - próba parsowania pustego stringa może rzucać takim błędem. Jeśli tak jest, to obstawiam, że przyczyna problemu leży w zapisywaniu do storage'u wartości ze zwróconego tokena z serwera, tutaj:

localStorage.setItem('token', JSON.stringify(res.token));

Pokaż odpowiedź (zawartość zmiennej res) z tego zapytania. Najlepiej z zakładki Network devtoolsów.

komentarz 13 stycznia 2021 przez HowToIT Początkujący (290 p.)
w login component console.log(response) wypisuje mi

key: 2f6f1447c51797fd239e0305a9e4518a7b260c6c

I tak, chodzi mi o Local Storage w Application, tam i w zakładce Network headers dostaję
Authorization: Bearer undefined
komentarz 13 stycznia 2021 przez ScriptyChris Mędrzec (190,190 p.)

Skoro w login component loguje poprawnie obiekt tokena (kluczem jest key a wartością string z tokenem), to pokaż co wyloguje konsola dla parametru res wewnątrz pipe -> tap w metodzie login. Chodzi mi o 20 linijkę z pliku UserService.ts - wstawiasz tam do storage zserializowaną wartość z res.token, a ja bym chciał zobaczyć, co jest w samej zmiennej res.

w zakładce Network headers dostaję
Authorization: Bearer undefined

Masz na myśli request header, czy response header? Najlepiej będzie jak pokażesz screen z tego requesta (jego zakładki Headers i Response).


Właściwie to odpowiedź na ostatnią prośbę z mojego poprzedniego komentarza również by się przydała:

Pokaż odpowiedź (zawartość zmiennej res) z tego zapytania. Najlepiej z zakładki Network devtoolsów.

komentarz 13 stycznia 2021 przez HowToIT Początkujący (290 p.)
Dodałam console.log(res) i wynik w konsoli jest taki sam jak poprzednio. W zakładce Network Authorization zmieniło się na: Bearer [object Object]
komentarz 14 stycznia 2021 przez ScriptyChris Mędrzec (190,190 p.)

Dodałam console.log(res) i wynik w konsoli jest taki sam jak poprzednio.

Tzn. jaki jest wynik - obiekt tokena? Wywołałaś ten console.log w metodzie login z UserService?

komentarz 14 stycznia 2021 przez HowToIT Początkujący (290 p.)
Tak, zaraz pod setItem. Wypisało

 {key: "2f6f1447c51797fd239e0305a9e4518a7b260c6c"}

1 odpowiedź

+1 głos
odpowiedź 14 stycznia 2021 przez ScriptyChris Mędrzec (190,190 p.)
wybrane 14 stycznia 2021 przez HowToIT
 
Najlepsza

Obstawiam, że przyczyną problemu jest odniesienie się do błędnego klucza z obiektu res.token zamiast res.key. Skoro obiekt nie zawiera property token to res.token zwraca undefined, który zapisujesz do Local Storage (to się zgadza z wpisem w zakładce Application). Natomiast próba użycia JSON.parse na wartości undefined rzuca błędem, który opisałaś.


Zamiana:

localStorage.setItem('token', JSON.stringify(res.token));

na:

localStorage.setItem('token', JSON.stringify(res.key));

powinna pomóc.

komentarz 14 stycznia 2021 przez HowToIT Początkujący (290 p.)

O matko tak! Dziękuję, dziękuję badzo! Nie wpadłabym na to nigdy enlightened

komentarz 14 stycznia 2021 przez ScriptyChris Mędrzec (190,190 p.)

Jestem całkowicie nowa w Angularze, więc jest to zlepek tutoriali

Na marginesie - dlaczego przerabiasz takie zaawansowane rzeczy, skoro nie znasz dobrze Angulara?

1
komentarz 14 stycznia 2021 przez HowToIT Początkujący (290 p.)
Projekt na studia, ambitnie w nowej technologii żeby się jej od razu nauczyć, ale jak wyszło tak wyszło.  Z Angularem znam się od jakiś dwóch tygodni. Do tej pory szło nieźle, ale na jwt całkowicie się zablokowałam.

Podobne pytania

+1 głos
1 odpowiedź 181 wizyt
+1 głos
1 odpowiedź 186 wizyt
pytanie zadane 12 listopada 2020 w JavaScript przez LixI Nowicjusz (130 p.)
0 głosów
1 odpowiedź 351 wizyt
pytanie zadane 20 maja 2020 w JavaScript przez mi-20 Stary wyjadacz (13,190 p.)

92,454 zapytań

141,262 odpowiedzi

319,089 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...