2016-08-29 6 views
5

Ich habe eine Login-Seite mit Angular 2 implementiert. Nach dem Login bekomme ich jsonwebtoken, userId, userRole, userName vom Server. Ich speichere diese Informationen im lokalen Speicher, damit ich jederzeit darauf zugreifen und den Anmeldestatus beibehalten kann, wenn der Benutzer die Seite aktualisiert.Angular 2 authenticate state

AuthService.ts

import {Injectable} from "@angular/core"; 

@Injectable() 
export class AuthService { 
    redirectUrl: string; 

    logout() { 
    localStorage.clear(); 
    } 

    isLoggedIn() { 
    return localStorage.getItem('token') !== null; 
    } 

    isAdmin() { 
    return localStorage.getItem('role') === 'admin'; 
    } 

    isUser() { 
    return localStorage.getItem('role') === 'user'; 
    } 

} 

den Login-Status zu überprüfen, Ich überprüfe nur, wenn Token in localstorage existiert. Da der lokale Speicher editierbar ist, würde das Hinzufügen eines Tokens im lokalen Speicher die Anmeldeseite umgehen. Wenn der Client die Benutzerrolle im lokalen Speicher bearbeitet, kann der Client auf einfache Weise auf Admin- oder Benutzerseiten zugreifen.

Wie löse ich diese Probleme?

Dies ist eher ein allgemeines Problem, ich möchte wissen, wie Websites den Anmeldestatus beibehalten?

P.S. NodeJS Server-Seite Login-Code generieren jsonwebtoken

const jwt = require('jsonwebtoken'); 
const User = require('../models/User'); 

/** 
* POST /login 
* Sign in using username and password 
*/ 
exports.postLogin = (req, res, next) => { 
    User.findOne({username: req.body.username}) 
     .then(user=> { 
      if (!user) { 
       res.status(401); 
       throw new Error('Invalid username'); 
      } 
      return user.comparePassword(req.body.password) 
       .then(isMatch=> { 
        if (isMatch != true) { 
         res.status(401); 
         throw new Error('Invalid password'); 
        } 
        let token = jwt.sign({user: user}, process.env.JWT_SECRET, { 
         expiresIn: process.env.JWT_TIMEOUT 
        }); 
        return res.status(200).json({ 
         success: true, 
         token: token, 
         userId: user._id, 
         role:user.role, 
         name:user.name 
        }); 
       }); 
     }) 
     .catch(err=>next(err)); 
}; 

-Danke

Antwort

0

1) Tokens soll einzigartig und schwer zu geben (wie eine großen Länge). Außerdem sollten sie mit einer gewissen Häufigkeit aktualisiert werden. Besser zu lesen oAuth docs auf diesem

2) Rollen sollten nicht auf der Client-Seite gespeichert werden. Nur auf dem Server überprüfen. Wenn Sie oAuth verwenden, sollten Sie auch Scopes verwenden.

0

Sie digital die Authentifizierungs-Token auf der Serverseite unterschreiben:

jwt.sign({user: user}, process.env.JWT_SECRET, { 
    expiresIn: process.env.JWT_TIMEOUT 
}) 

Diese Signatur dann von der Server-Seite auf nachfolgende Anforderungen überprüft werden soll. Es wird ungültig, wenn der Client den Inhalt des Tokens ändert.

0

Speicher Token in localStorage/sessionStorage und Validierungs Token mit Server wann immer erforderlich. Ich habe folgende Implementierung Token

UserProfileService.ts

@Injectable() 
export class UserProfileService { 
    private isLoggedIn: boolean = false; 
    private apiEndPoint: string; 
    constructor(private http: Http) { 
    this.apiEndPoint = environment.apiEndpoint; 
    } 

    login(token: string) { 
    localStorage.setItem('auth_token', token); 
    this.isLoggedIn = true; 
    } 

    logout(){ 
    localStorage.removeItem('auth_token'); 
    this.isLoggedIn = false; 
    } 

    isAuthorized(): Observable<boolean> { 
    if (!this.isLoggedIn) { 
     let authToken = localStorage.getItem('auth_token'); 
     if(authToken){ 
     let headers = new Headers(); 
     headers.append('Content-Type', 'application/json'); 
     headers.append('Accept', 'application/json'); 
     headers.append('Authorization', `Bearer ${authToken}`); 
     return this.http.get(`${this.apiEndPoint}/validate-token`, { headers: headers }) 
     .map(res => { 
      let serverResponse = res.json(); 
      this.isLoggedIn = serverResponse['valid']; 
      if (!this.isLoggedIn) { 
      localStorage.removeItem('auth_token'); 
      } 
      return this.isLoggedIn; 
     }) 
     .catch(this._serverError); 
     } 
    } 
    return Observable.of(this.isLoggedIn); 
    } 

    private _serverError(err: any) { 
    localStorage.removeItem('auth_token'); 
    if(err instanceof Response) { 
     console.log(err.json()); 
     return Observable.of(false); 
    } 
    return Observable.of(false); 
    } 

} 

AuthService.ts

@Injectable() 
export class CanActivateAuthGuard implements CanActivate, CanActivateChild, CanLoad { 
    constructor(private userProfileService: UserProfileService, private router: Router) { } 

    canLoad(route: Route) { 
    return this.userProfileService.isAuthorized().map(authorized => { 
     if(authorized) { 
     return authorized; 
     } else { 
     let url = `/${route.path}`; 
     this.router.navigate(['/login'], { queryParams: { redirectTo: url } }); 
     return authorized; 
     } 
    }); 
    } 

    canActivate(
    next: ActivatedRouteSnapshot, 
    state: RouterStateSnapshot 
) { 
    return this.userProfileService.isAuthorized().map(authorized => { 
     if(authorized) { 
     return authorized; 
     } else { 
     this.router.navigate(['/login'], { queryParams: { redirectTo: state.url } }); 
     return authorized; 
     } 
    }); 
    } 

    canActivateChild(
    route: ActivatedRouteSnapshot, 
    state: RouterStateSnapshot 
) { 
    return this.canActivate(route, state); 
    } 
} 
zu validieren