• 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

Aruba Cloud PRO i VPS, Openstack, VMWare, MS Hyper-V
+1 głos
148 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 (191,540 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 (191,540 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 (191,540 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 (191,540 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 (191,540 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ź 88 wizyt
+1 głos
1 odpowiedź 100 wizyt
pytanie zadane 12 listopada 2020 w JavaScript przez LixI Nowicjusz (130 p.)
0 głosów
1 odpowiedź 178 wizyt
pytanie zadane 20 maja 2020 w JavaScript przez mi-20 Stary wyjadacz (13,140 p.)

90,871 zapytań

139,544 odpowiedzi

313,813 komentarzy

60,356 pasjonatów

Motyw:

Akcja Pajacyk

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

Sklep oferujący ćwiczenia JavaScript, PHP, rozmowy rekrutacyjne dla programistów i inne materiały

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...