Angular:JWT Token 在 Postman 上运行良好,但在我的应用程序中运行良好

Posted

技术标签:

【中文标题】Angular:JWT Token 在 Postman 上运行良好,但在我的应用程序中运行良好【英文标题】:Angular: JWT Token works fine on Postman but not in my app 【发布时间】: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? 【参考方案1】:

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

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

【讨论】:

以上是关于Angular:JWT Token 在 Postman 上运行良好,但在我的应用程序中运行良好的主要内容,如果未能解决你的问题,请参考以下文章

Angular 5 路由器插座,JWT

Angular:JWT Token 在 Postman 上运行良好,但在我的应用程序中运行良好

Spring Security Jwt Token在请求表单角度时允许所有Options方法

如何使用 HttpClientXsrfModule angular 6 添加 x-xsrf-token

Angular 和 JWT - 客户端如何验证令牌?

Spring Boot + Angular 2 + JWT