angular + nodejs 控制台显示“GET http://localhost:4200/user/profile 401 (Unauthorized)”
Posted
技术标签:
【中文标题】angular + nodejs 控制台显示“GET http://localhost:4200/user/profile 401 (Unauthorized)”【英文标题】:angular + nodejs console shows "GET http://localhost:4200/user/profile 401 (Unauthorized) " 【发布时间】:2020-10-20 06:58:18 【问题描述】:我正在尝试在登录后将数据存储到 /profile。但是,我在登录后一直在控制台中收到这 2 个错误。
"VM276:1 GET http://localhost:4200/user/profile 401 (未授权)" 和“HttpErrorResponse headers: HttpHeaders, status: 401, statusText: "Unauthorized"”。
由于我遵循不同的教程来解决这个问题,所以我知道我在令牌代码上犯了一些错误,我只是不知道如何修复它。我要感谢任何花时间提供帮助的人!这是我的 authentication.service.ts
import Injectable from '@angular/core';
import HttpClient from "@angular/common/http";
import Observable, of from 'rxjs';
import map from 'rxjs/operators';
import Router from '@angular/router';
export interface UserDetails
username: string
email: string
password: string
exp: number
iat: number
interface TokenResponse
token: string
export interface TokenPayload
username: string
email: string
password: string
@Injectable(
providedIn: 'root'
)
export class AuthenticationService
private token: string
constructor(private http: HttpClient, private router: Router)
private saveToken(token: string): void
localStorage.setItem('usertoken', token)
this.token = token
private getToken(): string
if(!this.token)
this.token = localStorage.getItem('usertoken')
return this.token
public getUserDetails(): UserDetails
const token = this.getToken()
let payload
if(token)
payload = token.split('.')[1]
payload = window.atob(payload)
return JSON.parse(payload)
else
return null
public isLoggedIn(): boolean
const user = this.getUserDetails()
if(user)
return user.exp > Date.now()/ 1000
else
return false
public login(user: TokenPayload): Observable<any>
const base = this.http.post('/user/login', user)
const request = base.pipe(
map((data: TokenResponse) =>
if(data.token)
this.saveToken(data.token)
return data
)
)
return request
public register(user: TokenPayload) : Observable<any>
const base = this.http.post('/user/register', user)
const request = base.pipe(
map((data: TokenResponse) =>
if(data.token)
this.saveToken(data.token)
return data
)
)
return request
public profile(): Observable<any>
return this.http.get('/user/profile',
headers: Authorization: `$this.getToken()`
)
public logout(): void
this.token = ''
window.localStorage.removeItem('usertoken')
this.router.navigateByUrl('/')
这是我的 profile.component.ts
export class ProfileComponent implements OnInit
details: UserDetails
constructor(private auth: AuthenticationService)
ngOnInit()
this.auth.profile().subscribe(
user =>
this.details = user
,
err =>
console.error(err)
)
这是我的 auth.js
const jwt = require("jsonwebtoken");
module.exports = function(req, res, next)
const token = req.header("token");
if (!token) return res.status(401).json( message: "Auth Error" );
try
const decoded = jwt.verify(token, "randomString");
req.user = decoded.user;
next();
catch (e)
console.error(e);
res.status(500).send( message: "Invalid Token" );
;
这是我的 /routes/user.js
// Filename : user.js
const express = require("express");
const check, validationResult = require("express-validator");
const bcrypt = require("bcryptjs");
const jwt = require("jsonwebtoken");
const router = express.Router();
const auth = require("../middleware/auth");
const User = require("../model/User");
/**
* @method - POST
* @param - /signup
* @description - User SignUp
*/
router.post(
"/register",
[
check("username", "Please Enter a Valid Username")
.not()
.isEmpty(),
check("email", "Please enter a valid email").isEmail(),
check("password", "Please enter a valid password").isLength(
min: 6
)
],
async (req, res) =>
const errors = validationResult(req);
if (!errors.isEmpty())
return res.status(400).json(
errors: errors.array()
);
const
username,
email,
password
= req.body;
try
let user = await User.findOne(
email
);
if (user)
return res.status(400).json(
msg: "User Already Exists"
);
user = new User(
username,
email,
password
);
const salt = await bcrypt.genSalt(10);
user.password = await bcrypt.hash(password, salt);
await user.save();
const payload =
user:
id: user.id
;
jwt.sign(
payload,
"randomString",
expiresIn: 10000
,
(err, token) =>
if (err) throw err;
res.status(200).json(
token
);
);
catch (err)
console.log(err.message);
res.status(500).send("Error in Saving");
);
router.post(
"/login",
[
check("email", "Please enter a valid email").isEmail(),
check("password", "Please enter a valid password").isLength(
min: 6
)
],
async (req, res) =>
const errors = validationResult(req);
if (!errors.isEmpty())
return res.status(400).json(
errors: errors.array()
);
const email, password = req.body;
try
let user = await User.findOne(
email
);
if (!user)
return res.status(400).json(
message: "User Does Not Exist"
);
const isMatch = await bcrypt.compare(password, user.password);
if (!isMatch)
return res.status(400).json(
message: "Incorrect Password!"
);
const payload =
user:
id: user.id
;
jwt.sign(
payload,
"randomString",
expiresIn: 3600
,
(err, token) =>
if (err) throw err;
res.status(200).json(
token
);
);
catch (e)
console.error(e);
res.status(500).json(
message: "Server Error"
);
);
/**
* @method - POST
* @description - Get LoggedIn User
* @param - /user/me
*/
router.get("/profile", auth, async (req, res) =>
try
// request.user is getting fetched from Middleware after token authentication
const user = await User.findById(req.user.id);
res.json(user);
catch (e)
res.send( message: "Error in Fetching user" );
);
module.exports = router;
【问题讨论】:
【参考方案1】:在您的 Angular 应用中,您发送带有 authorization
标头的令牌
Authorization: token
但是在您的 API (auth.js
) 中,您正在尝试访问 token
标头
req.header("token")
将您的 api 代码替换为
req.header("authorization")
【讨论】:
以上是关于angular + nodejs 控制台显示“GET http://localhost:4200/user/profile 401 (Unauthorized)”的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Mongoose、Express、Angular 4 和 NodeJS 上传/保存和显示图片
Mysql 表数据未显示在使用 Nodejs 的 Angular 材料表上
从 mongoDB 获取数据并使用 Angular 和 NodeJs 在屏幕上打印