[英]Angular: JWT Token works fine on Postman but not in my app
I'm a bit of a beginner with Angular so please bear with me.我是 Angular 的初学者,所以请多多包涵。
I have a simple app which allows people to register, login and retrieve their own user data (which is the part I am stuck at).我有一个简单的应用程序,它允许人们注册、登录和检索他们自己的用户数据(这是我坚持的部分)。
Backend user.routes.js
:后端
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);
}
Backend user.controller.js
:后端
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'
])
)
}
Backend user.service.ts
:后端
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');
}
And finally, my backend auth.js
:最后,我的后端
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);
}
}
On my dashboard, I do a very simple request:在我的仪表板上,我做了一个非常简单的请求:
this.userService.getProfile().subscribe(data => (this.profile = data));
Now, my problem is the following:现在,我的问题如下:
Using Postman, if I do a POST
request to /login
, I get a token back.使用 Postman,如果我向
/login
发出POST
请求,我会得到一个令牌。 Everything fine so far.到目前为止一切都很好。 And if I use this token (in Postman) in my next
GET
request to /getuser
, I also get the results I want (email, firstName, lastName, accountType of the user).如果我在对
/getuser
的下一个GET
请求中使用这个令牌(在 Postman 中),我也会得到我想要的结果(用户的电子邮件、名字、姓氏、帐户类型)。
However, the problem is on the front-end.但是,问题出在前端。 I login and arrive to the main page (no issues there), but once
getProfile()
is called, I get a GET http://localhost:3001/getuser 401 (Unauthorized)
.我登录并到达主页(那里没有问题),但是一旦调用
getProfile()
,我就会得到一个GET http://localhost:3001/getuser 401 (Unauthorized)
。 I've been stuck on this for hours and not sure where the problem is from.我已经坚持了几个小时,不确定问题出在哪里。
I appreciate any help I can get.我很感激我能得到的任何帮助。
Thanks!谢谢!
I found my issue.我发现了我的问题。 I had forgotten to add the Interceptor I had created to my providers in
app.module.ts
.我忘记将我创建的拦截器添加到
app.module.ts
中的提供程序。
// Auth
{
provide: HTTP_INTERCEPTORS,
useClass: JwtHttpInterceptor,
multi: true
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.