【问题标题】:Angular: JWT Token works fine on Postman but not in my appAngular:JWT Token 在 Postman 上运行良好,但在我的应用程序中运行良好
【发布时间】:2020-03-05 14:02:24
【问题描述】:

我是 Angular 的初学者,所以请多多包涵。

我有一个简单的应用程序,它允许人们注册、登录和检索他们自己的用户数据(这是我坚持的部分)。

后台user.routes.js

const auth = require('./middlewares/auth')

module.exports = (app) => {
    const user = require('./user.controller.js');

    app.post('/login', user.login);
    app.post('/register', user.register);
    app.get('/getuser', auth, user.getuser);
}

后台user.controller.js:

exports.getuser = async (req, res, next) => {
  let user

  try {
    user = await User.findById(req.payload._id)
  } catch (err) {
    next(new InternalServerError('Could not fetch user', err))
    return
  }

  if (!user) {
    next(new NotFoundError('User not found'))
    return
  }

  res.json(
    pick(user, [
      'email',
      'firstName',
      'lastName',
      'accountType'
    ])
  )
}

后台user.service.ts

@Injectable()
export class UserService {
  private _isLoggedIn: BehaviorSubject<boolean> = new BehaviorSubject(false);
  public readonly isLoggedIn$ = this._isLoggedIn.asObservable();

  constructor(private http: HttpClient) {
    this._isLoggedIn.next(this.isLoggedIn());
  }

  login(
    email: string,
    password: string,
    rememberMe = false
  ): Observable<boolean | any> {
    return this.http
      .post<LoginResponse>('http://localhost:3001/login', { email, password })
      .map(res => {
        setToken(res.token, rememberMe);
        this._isLoggedIn.next(true);
        return true;
      })
      .catch(this.handleError);
  }

  register(
    email: string,
    password: string,
    lastName: string,
    firstName: string
  ): Observable<boolean | any> {
    return this.http
      .post<LoginResponse>('http://localhost:3001/register', {
        email,
        password,
        lastName,
        firstName
      })
      .map(res => {
        setToken(res.token);
        return true;
      })
      .catch(this.handleError);
  }

  logout() {
    removeToken();
  }

  isLoggedIn() {
    return tokenNotExpired();
  }

  getProfile() {
    return this.http.get<Profile>('http://localhost:3001/getuser');
  }

最后,我的后端auth.js

// Dependencies
import { JwtHelperService } from '@auth0/angular-jwt';

// Angular
import {
  HttpEvent,
  HttpHandler,
  HttpInterceptor,
  HttpRequest
} from '@angular/common/http';
import { Injectable } from '@angular/core';

// RXJS
import { Observable } from 'rxjs/Observable';

// Environment
import { DecodedToken } from './decoded-token';

// Services
const helper = new JwtHelperService();

// Constants
export const TOKEN_NAME = 'access_token';

// Exports
export function getToken(storage = null) {
  if (storage) {
    const token = storage.getItem(TOKEN_NAME);
    if (token && !helper.isTokenExpired(token)) {
      return token;
    }
    removeToken(storage);
    return null;
  }

  return getToken(localStorage) || getToken(sessionStorage);
}

export function setToken(token: string, rememberMe = false) {
  const storage = rememberMe ? localStorage : sessionStorage;

  storage.setItem(TOKEN_NAME, token);
}

export function removeToken(storage = null) {
  if (storage) {
    storage.removeItem(TOKEN_NAME);
  } else {
    localStorage.removeItem(TOKEN_NAME);
    sessionStorage.removeItem(TOKEN_NAME);
  }
}

export function tokenNotExpired() {
  return !helper.isTokenExpired(getToken());
}

export function decodeToken(): DecodedToken {
  return helper.decodeToken(getToken());
}

@Injectable()
export class JwtHttpInterceptor implements HttpInterceptor {
  constructor() {}
  intercept(
    request: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    const token = getToken();
    let clone: HttpRequest<any>;
    if (token) {
      clone = request.clone({
        setHeaders: {
          Accept: `application/json`,
          'Content-Type': `application/json`,
          Authorization: `Bearer ${token}`
        }
      });
    } else {
      clone = request.clone({
        setHeaders: {
          Accept: `application/json`,
          'Content-Type': `application/json`
        }
      });
    }
    return next.handle(clone);
  }
}

在我的仪表板上,我做了一个非常简单的请求:

this.userService.getProfile().subscribe(data => (this.profile = data));

现在,我的问题如下:

使用 Postman,如果我向 /login 发出 POST 请求,我会得到一个令牌。到目前为止一切都很好。如果我在对/getuser 的下一个GET 请求中使用这个令牌(在邮递员中),我也会得到我想要的结果(用户的电子邮件、名字、姓氏、帐户类型)。

但是,问题出在前端。我登录并到达主页(那里没有问题),但是一旦调用 getProfile() ,我就会得到一个 GET http://localhost:3001/getuser 401 (Unauthorized) 。我已经坚持了好几个小时了,不知道问题出在哪里。

感谢我能得到的任何帮助。

谢谢!

【问题讨论】:

  • 您是否检查过(使用 DevTools)发送到 API 的请求是否包含 Authorization 标头?
  • 这可能是问题所在。但是我想用我设置 auth.js 的方式,请求应该包含 Authorization 标头?我该如何解决这个@KamilChlebek?

标签: node.js angular jwt


【解决方案1】:

我发现了我的问题。我忘记将我创建的拦截器添加到app.module.ts 中的提供程序。

  // Auth
  {
    provide: HTTP_INTERCEPTORS,
    useClass: JwtHttpInterceptor,
    multi: true
  }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-11-16
    • 1970-01-01
    • 2020-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多