Angular 2验证状态 [英] Angular 2 authenticate state

查看:131
本文介绍了Angular 2验证状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用Angular 2实现了登录页面。登录后,我从服务器获取jsonwebtoken,userId,userRole,userName。我将此信息存储在localstorage中,以便我可以随时访问它并在用户刷新页面时保持登录状态。

I've implemented a login page using Angular 2. After login, I get jsonwebtoken, userId, userRole, userName from server. I'm storing this info in localstorage so that I can access it any time and maintain login state if user refreshes page.

AuthService.ts

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';
  }

}

要检查登录状态,我我只是检查localstorage中是否存在令牌。由于localstorage是可编辑的,因此只需在localstorage中添加任何令牌即可绕过登录页面。同样,如果客户端在localstorage中编辑用户角色,客户端可以轻松访问管理员或用户页面。

To check the login status, I'm just checking if token exists in localstorage. As localstorage is editable so just adding any token in localstorage would bypass login page. Similarly, if client edit user role in localstorage, client can easily access admin or user pages.

如何解决这些问题?

这更像是一般问题,我想知道网站如何保持登录状态?

This is more like a general problem, I want to know how websites maintain login status?

P.S。
NodeJS服务器端登录代码生成jsonwebtoken

P.S. NodeJS Server side login code to generate 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));
};

-Thanks

推荐答案

在localStorage / sessionStorage中存储令牌,并在需要时使用服务器验证令牌。我有以下实现来验证令牌

store token in localStorage/sessionStorage and validate token with server whenever required. I am having following implementation to validate token

UserProfileService.ts

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

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);
  }
}

这篇关于Angular 2验证状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆